;HELLO Alan Bailey is the name ;I'm posting this source for a few reasons ; 1) people have asked for it ; 2) I've decided I'm done with it ; 3) the little people in my head told me to ; ;So...try to learn something frm it. It's not commented and I didn't want it to be. ;Mostly it is for people trying to implement something like it themselves. ; ;contact me if you have any questions: ; ;Alan Bailey ;mailto:bailela@charlie.cns.iit.edu ;Web: http://www.iit.edu/~bailela/ ;IRC: Abalone on #ticalc, #ti-files on Efnet ; ;BYE!!! #include "ti-85.h" .org 0 .db "ZTerm v.9b by Alan Bailey",0 ;$8BE1 ;$8BE5 ;the real ones thankfully ;finished the vt100 commands1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 ;FINISHED THE VT100 COMMANDS ;{April 23, 1997...fixed that thing with the cursor...it had to do with getkeys ;VARIABLE DEFINITIONS: length | description ;------------------------------|-------------------------------- cursorcount = $80DF ;byte | counter for the cursor state1 = $80E0 ;byte | ASCII code for cursor displayed ($7C or $20) state2 = $80E1 ;byte | ASCII code for cursor not displayed ^^^^ cursorstate = $80E2 ;byte | 0-norm 1-second 2-big 3-small cursorstate2 = $80E3 ;byte | same parameters ^^, secondary value used in editing function keys cursorcoords = $80E4 ;word | coords of cursor($xxyy), $FFFF if not on screen cursoraddress = $80E6 ;word | pointer in mem of place to write to startbuffer = $80E8 ;word | pointer to first line of data endbuffer = $80EA ;word | pointer to line containing cursoraddress <------\ realendbuffer = $811A ;word | the pointer to the actual end, not just the one ^^^^ memend = $80EC ;word | pointer to last line that can contain data displaystart = $80EE ;word | pointer to line at the top of the screen currrow = $80F0 ;word | used in displaystart, first line to put on screen displaycolumn = $80F2 ;byte | column number on left of screen linestodisplay = $80F3 ;byte | number of lines to display after and inclusive of currrow vt100_on = $80F4 ;byte | For all of these, 1 if set, 0 if not localecho_on = $80F5 ;byte | Preferences of terminal outboundCRLF_on = $80F6 ;byte | These MUST stay in the same order, inboundCRLF_on = $80F7 ;byte | don't change splitscreen_on = $80F8 ;byte | ------------- currentpref = $80F9 ;word | pointer to current pref selected currentmenu = $80FB ;word | pointer to current menu shown currentFkey = $80FD ;byte | Fkey chosen in function key edit ($31('1')-$35('5')) Fkeyaddress = $80FE ;word | pointer to current line of function key chosen Fkeycursor = $8100 ;byte | cursor value for editing of function keys sendoutbuffer = $8A11 ; 32 | this is in the graphmem dispoutbuffer = $89F1 ; 32 | this is before the sendoutbuffer in the graphmem storedcoords = $8101 ;word | stores the coords from the vt100 command storedline = $8103 ;word | stores endbuffer from the vt100 command vt100charattrib = $8105 ;byte | vt100 command sets display style ; | bit 0 set - bold on ; | bit 1 set - underscore on ; | bit 2 set - blink on ; | bit 3 set - reverse on inputbufferstart = $8106 ;word | pointer to buffer to store incoming data buffercursor = $8108 ;word | pointer of current place to write to beginbufferdata = $810A ;word | pointer to beginning of data to process inputbufferend = $810C ;word | pointer to end of place to store incoming data bufferhasdata = $810E ;byte | set to 1 if data is waiting to be processed sendouthasdata = $810F ;byte | set to 1 if data waiting to be sent dispouthasdata = $8110 ;byte | set to 1 if data waiting to be displayed unpacknumber = $8111 ; 3 | 3 bytes for displaying ascii digits totallines = $8114 ;word | totallines for use by ZTerm startoverind = $8116 ;byte | indicator to tell if should display stuff during beg absnowork = $8117 ;byte | set if no mem for program to work at all absnovt100 = $8118 ;byte | set if no mem for vt100 to work at all bellcounter = $8119 ;byte | counter to keep bell on screen ;$811A used ;$811B used firstline = $811C ;word | first line of vt100screen lastline = $811E ;word | last line of vt100 screen firstscroll = $8120 ;word | first scrolling line lastscroll = $8122 ;word | last scrolling line stored_key = $8124 ;byte | stored key to check for key repeats ;(------------------Start of the program-------------------) ;|This is where the program starts. | ;|All the initialization stuff is in here | ;(---------------------------------------------------------) ld a,0 ;these designate that the screen should be displayed this time ld (startoverind),a ;if 1, don't display the screen after all initialization start: ld hl,ZS_BITS ;allows bytes in ZTerm to be changed set 0,(hl) ;/ ld hl,(PROGRAM_ADDR) ;\ ld de,savedprefs ; \ add hl,de ;Loads the saved preferences ld de,vt100_on ; / ld bc,00005 ; / ldir ;/ ld hl,(PROGRAM_ADDR) ld de,tabtable ; add hl,de ; ld (hl),0 ; ld b,9 ;loads the tabs into place loadtabsloop: inc hl ld (hl),%10000000 djnz loadtabsloop set 0,(hl) ;and the final tab is there ld hl,sendoutbuffer ;zeroes out any stuff in the sendoutbuffer ld a,$00 ;and in the dispoutbuffer ld (hl),a ;that's why the 63 is there push hl pop de inc de ld bc,00063 ldir ;like that ld hl,$207C ; $20 = space $7C = horizontal bar ld (state1),hl ;initialize stuff ld a,0 ;\/ ld (cursorcount),a ;\/ ld (cursorstate),a ;\/ ld (cursorstate2),a ;\/ ld (displaycolumn),a ;\/ ld ($8333),a ld ($8334),a ld (sendouthasdata),a ld (bufferhasdata),a ld (dispouthasdata),a ;all the previous things are started at zero ld hl,$0000 ld (cursorcoords),hl ;first cursor spot at (0,0) ld hl,$8BE5 ;this is the end of the free memory call LD_HL_MHL push hl ;it's needed twice in the future push hl ld hl,$8BE1 ;this is the beginning of the free mem call LD_HL_MHL ld (inputbufferstart),hl ;beginning of mem for these three variables ld (buffercursor),hl ld (beginbufferdata),hl ld de,$07FF ;check if not enough later!!!! <--------- add hl,de ;$07FF+1 is length of the receive byte buffer pop de push hl ;holds hl for 6 lines scf ccf sbc hl,de bit 7,h JUMP_Z(nomemforbuffer) pop hl ld (inputbufferend),hl ;this is the end of it inc hl ;get to the correct place for displaystart and all that pop de ;loads the thing that used to be in hl ld (displaystart),hl ;these are all past the 2048 at the beginning ld (currrow),hl ;beginning variables for the display buffer ld (cursoraddress),hl ld (startbuffer),hl ld (endbuffer),hl ld (firstline),hl ld (firstscroll),hl push hl ld bc,01520 ;80*19 add hl,bc ld (realendbuffer),hl ld (lastline),hl ld (lastscroll),hl pop hl push hl ex de,hl ;now...hl=end buffer de=start buffer sbc hl,de ;this finds the difference ld a,h ;\/All of these things do something like a mod thing ld c,l ;with 16 bit ld de,00080 CALL_(div) ;ac outputs with number of lines ld d,a ;\/ ld e,c push de pop hl ld (totallines),hl ;puts it in here for use with begin screen ld a,80 CALL_(mult) ;\/ hl is outputted with the number of lines * 80 pop de ;de is the start add hl,de ;add to find the end ld bc,00800 ;this subtracts 80 to be sure you don't write over scf ccf sbc hl,bc ;anything ld (memend),hl ;and there you have it, the last variable for the last line add hl,bc ;this increases it again for this clearing routine ex de,hl ;now de is the end and hl is beginning ld hl,(inputbufferstart) clearmem: ld (hl),0 ;clears all the stuff in mem takes a while.. inc hl call CP_HL_DE jr nz,clearmem ld a,(startoverind) cp 1 JUMP_Z(intsetup) ;skips the screen, ints back on, terminal time ;used when CLEAR is pressed ;this is the beginning of displaying things dispbeginscreen CALL_(clearscreen) ld hl,(PROGRAM_ADDR) ld de,ztermpicture add hl,de ld de,$FC04 ld bc,00226 ldir ld hl,$0F24 ld ($8333),hl ld hl,(PROGRAM_ADDR) ld de,screenwords add hl,de ROM_CALL(D_ZM_STR) push hl ld hl,$0303 ld ($800C),hl pop hl ROM_CALL(D_ZT_STR) push hl ld hl,$2116 ld ($8333),hl pop hl ROM_CALL(D_ZM_STR) push hl ld hl,$2E00 ld ($8333),hl pop hl ROM_CALL(D_ZM_STR) push hl ;saved for lang way off ld hl,(totallines) ld de,unpacknumber+2 ld b,3 unpackloop: call UNPACK_HL add a,'0' ld (de),a dec de djnz unpackloop inc de ex de,hl ld b,3 ROM_CALL(D_LM_STR) ;number pop hl ;saved address for words ROM_CALL(D_ZM_STR) ;"lines" ld hl,(totallines) ld a,l add a,$10 jr c,dispdiag4 ;if after adding 16, it carried over, means over 240 bit 7,l jr nz,dispdiag3 ;if bit 7 of l is set, over 127 ld a,l add a,12 bit 5,a jr nz,dispdiag2 ;if any of the top three bits are set, over 31 ld a,l add a,6 bit 4,a jr nz, dispdiag1 ;if bit 4 set after adding 5, over 10 jr dispdiag0 ;or go here, NO MEM!!! dispdiag4: ld de,diagnosis4 jr dispdiagnosis dispdiag3: ld de,diagnosis3 jr dispdiagnosis dispdiag2: ld de,diagnosis2 jr dispdiagnosis dispdiag1: ld de,diagnosis1 ;no room for vt100 stuff ld a,1 ld (absnovt100),a ld a,0 ld (vt100_on),a jr dispdiagnosis dispdiag0: ld de,diagnosis0 ;no room for anything ld a,1 ld (absnowork),a jr dispdiagnosis dispdiagnosis: ld hl,(PROGRAM_ADDR) add hl,de ;de from previous routines ROM_CALL(D_ZM_STR) ld a,$FF ld hl,$FD60 ld de,$FD61 ld (hl),a ld bc,00015 ldir ;this puts a horiz line CALL_(displaymenu) ld hl,$3A05 ld ($8333),hl ld hl,(PROGRAM_ADDR) ld de,menuwords add hl,de ROM_CALL(D_ZM_STR) ld a,$1E ld ($8333),a ROM_CALL(D_ZM_STR) ld a,$38 ld ($8333),a ROM_CALL(D_ZM_STR) ld a,$51 ld ($8333),a ROM_CALL(D_ZM_STR) beginkeys: call GET_KEY cp K_F1 JUMP_Z(intsetup) ;start interrupts, analogous to starting terminal cp K_F2 JUMP_Z(showkeys) cp K_F3 JUMP_Z(showhelp) cp K_EXIT JUMP_Z(exittime) cp K_F4 JUMP_Z(exittime) jr beginkeys nomemforbuffer: pop hl pop hl ;get extra things off stack ld hl,$0000 ld (totallines),hl ;less than enough room JUMP_(dispbeginscreen) exittime: im 1 ret showkeys: CALL_(helpkeyscreen) JUMP_(start) showhelp: CALL_(helpscreen) JUMP_(start) helpscreen: CALL_(clearscreen) ld hl,$0000 ld ($8333),hl ld hl,(PROGRAM_ADDR) ld de,helpaddress add hl,de ld b,6 helpscreenloop: ROM_CALL(D_ZM_STR) push hl ld hl,($8333) ld a,7 add a,h ld l,0 ld h,a ld ($8333),hl pop hl djnz helpscreenloop helpscreenkeylop: call GET_KEY cp K_EXIT ret z jr helpscreenkeylop helpkeyscreen: CALL_(clearscreen) ld hl,$0000 ld ($8333),hl ld hl,(PROGRAM_ADDR) ld de,keyhelpwords add hl,de ld b,9 helpkeyloop: ROM_CALL(D_ZM_STR) push hl ld hl,($8333) ld a,7 add a,h ld l,0 ld h,a ld ($8333),hl pop hl djnz helpkeyloop helpkeykeyloop: call GET_KEY cp K_EXIT ret z jr helpkeykeyloop ;(----------Sets up the interrupt routines----------) ;(--------------------------------------------------) intsetup: ld a,(absnowork) bit 0,a JUMP_NZ(beginkeys) CALL_(clearscreen) ;right after all that stuff is on the screen ld a,$88 ;loads $8888 ld hl,$8700 ;into 256 bytes ld (hl),a ; ld de,$8701 ld bc,$00FF ldir ld hl,(PROGRAM_ADDR) ;start of the program ld de,introut ;finds the routine sitting at the end add hl,de ; like that ld de,$8888 ;and this is the place we want to load it. ld bc,introutend+1-introut ;finds the lentgh of the routine ldir ;and puts it ld a,$87 ;this is the place we want to jump in vector ld i,a ;register im 2 ;starts it up........ ld a,10 ld (linestodisplay),a CALL_(displayscreen) ;and displsys the screen, which has nothing ;right now ;(--------------------------Main Loop-------------------------) ;|This is the loop the program is in when it's not doing other| ;|things. This loop manages the buffers, the keys, and the | ;|port. | ;|Input: none | ;|Output: none | ;(------------------------------------------------------------) mainloop: CALL_(recievebyte) ;this is the most important thing or a JUMP_NZ(putdatain) ;jump to store it ld a,(sendouthasdata) ;you want to do these two before processdatabuff or a ;because it can put stuff in these JUMP_NZ(processsendout) ld a,(dispouthasdata) or a JUMP_NZ(processdispout) call GET_KEY ;least important thing is the keypresses :( or a JUMP_NZ(loopitup) ld a,(bufferhasdata) or a JUMP_NZ(processdatabuff) jr mainloop ;or go back to the main loop ;(--------------------------------------------------) ;|This small loop is here because the routine | ;|putindatabuffer is called to, while mainloop jumps| ;|to everything, so you need this | ;|Input: a contains character to put | ;|Output: none | ;(--------------------------------------------------) putdatain: CALL_(putindatabuffer) JUMP_(mainloop) ;(----------------Puts data from port to buffer----------------) ;|Takes data just recieved from port and puts it into buffer | ;|to be processed later | ;|Input: a contains character to put in buffer | ;|Output: (bufferhasdata) is set because data was put in | ;(-------------------------------------------------------------) putindatabuffer: ld hl,(buffercursor) ld (hl),a ld de,(inputbufferend) call CP_HL_DE jr z,movetobeginning inc hl putindatabuffer2: ld (buffercursor),hl ld a,$01 ld (bufferhasdata),a ret movetobeginning: ld hl,(inputbufferstart) jr putindatabuffer2 ;(---------------Processes data in buffer------------------) ;|Takes data in the buffer and acts on it if it's a vt100 | ;|command sequence, or it just puts it in another buffer to| ;|put it on the screen. Changes variables of buffer if | ;|necessary NOTE: only jumped to from mainloop: | ;|Input: none } | ;|Output: none }just data management | ;(---------------------------------------------------------) processdatabuff: ld hl,(beginbufferdata) ld a,(hl) cp $1B CALL_Z(vt100time) cp $0D CALL_Z(changeCRLF_ifnec) ld c,0 cp $00 CALL_NZ(putindispout) ld hl,(beginbufferdata) ld de,(inputbufferend) call CP_HL_DE jr z,movetobeginning2 inc hl processdatabuff2: ld (beginbufferdata),hl ld de,(buffercursor) call CP_HL_DE CALL_Z(nomoredata) JUMP_(mainloop) nomoredata: ld a,$00 ld (bufferhasdata),a ;ld hl,(inputbufferstart) ;ld (buffercursor),hl ;ld (beginbufferdata),hl ret movetobeginning2: ld hl,(inputbufferstart) jr processdatabuff2 ;(---------------------Change CR to CR/LF---------------) ;|This adds a LF ($0A) if a CR ($0D) is encountered | ;|of course, only if necessary. Puts both in buffer to | ;|display, or returns with a 0 in a to skip the loop | ;|in mainloop. | ;|Input: none | ;|Output: a = 0 to skip the check in mainloop | ;(------------------------------------------------------) changeCRLF_ifnec: ld hl,inboundCRLF_on bit 0,(hl) jr z,changeCRLF2 ld hl,(PROGRAM_ADDR) ld de,crlftable add hl,de ld c,2 CALL_(putindispout) ld a,0 changeCRLF2: ret ;(-------------Puts data in buffer waiting to be sent out----------) ;|This takes strings or single chars and throws them in a buffer to| ;|wait to be sent out | ;|Input: c = length of string; hl = pointer to string | ;| if c=0, then a contains single byte to put | ;|Output: puts in buffer, eventually to be put out link port | ;(-----------------------------------------------------------------) putinsendout: ;is called with address in hl, length in c push af ;if c is zero, one byte to be sent is in a ld a,c ld de,sendoutbuffer cp 0 jr z,onebytetosend ld (sendouthasdata),a pop af ld b,0 ldir ret onebytetosend: ld a,1 ld (sendouthasdata),a pop af ld (de),a ret ;(-------------Sends out the stuff in the send out buffer---------) ;|This takes the first byte in the send out buffer and...sends it.| ;|Moves all the other waiting data down a byte | ;|Input: none | ;|Output: sends stuff finally through the link port | ;(----------------------------------------------------------------) processsendout: ld a,(sendoutbuffer) CALL_(sendbyte) ld hl,sendoutbuffer push hl pop de inc hl ld bc,00031 ldir ld a,(sendouthasdata) dec a ld (sendouthasdata),a JUMP_(mainloop) ;(-------------Puts data in buffer waiting to be displayed---------) ;|This takes strings or single chars and throws them in a buffer to| ;|wait to be displayed on the screen | ;|Input: c = length of string; hl = pointer to string | ;| if c=0, then a contains single byte to put | ;|Output: puts in buffer, eventually to be displayed on screen | ;(-----------------------------------------------------------------) putindispout: ;is called with address in hl, length in c push af ;if c is zero, one byte to be sent is in a ld a,c ;saves a ld de,dispoutbuffer cp 0 jr z,onebytetodisp ld (dispouthasdata),a pop af ld b,0 ;c is still untouched ldir ret onebytetodisp: ld a,1 ld (dispouthasdata),a pop af ld (de),a ret ;(-------------Displays the stuff in the display out buffer-----------) ;|This takes the first byte in the display out buffer and displays it.| ;|Moves all the other waiting data down a byte | ;|Input: none | ;|Output: Dislpays stuff finally on the screen | ;(--------------------------------------------------------------------) processdispout: ld a,(dispoutbuffer) CALL_(charinbuffer) ld hl,dispoutbuffer push hl pop de inc hl ld bc,00031 ldir ld a,(dispouthasdata) dec a ld (dispouthasdata),a JUMP_(mainloop) ;(--------------BIG KEY CHECK LOOP-------------------) ;|The biggest key check loop you'll ever find. Jumps| ;|to many different places, which go back to mainloop| ;|eventually | ;|Input: a contains the keypress | ;|Output: none | ;(---------------------------------------------------) loopitup: cp K_EXIT ;this exits after turning the interrupts off JUMP_Z(timetogo) cp K_RIGHT ;go to the scrollright routine JUMP_Z(scrollright) cp K_LEFT ;scrollleft JUMP_Z(scrollleft) cp K_DOWN JUMP_Z(scrolldown) cp K_UP JUMP_Z(scrollup) cp K_CUSTOM ;sets preferences JUMP_Z(termprefs) cp K_MORE ;extended chars JUMP_Z(sendmorechars) cp K_ENTER ;enter key JUMP_Z(enterkey) cp K_DEL ;del key JUMP_Z(delkey) cp K_CLEAR JUMP_Z(clearscreenbuff) cp K_GRAPH JUMP_Z(refreshscreen) cp K_STAT JUMP_Z(dispthekeyscreen) cp K_F1 JUMP_Z(putF1) cp K_F2 JUMP_Z(putF2) cp K_F3 JUMP_Z(putF3) cp K_F4 JUMP_Z(putF4) cp K_F5 JUMP_Z(putF5) cp 0 JUMP_NZ(figure) JUMP_(mainloop) dispthekeyscreen: im 1 CALL_(helpkeyscreen) ld a,10 ld (linestodisplay),a ld hl,(displaystart) ld (currrow),hl CALL_(clearscreen) CALL_(displayscreen) im 2 JUMP_(mainloop) ;(----------------Clears the buffer----------------------) clearscreenbuff: ld a,1 ld (startoverind),a JUMP_(start) ;(--------------Refreshes the screen---------------------) ;|Displays the whole screen again, based on the variables| ;|but first clearing screen | ;|Input: none | ;|Output: new clean screen!!! | ;(-------------------------------------------------------) refreshscreen: ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) JUMP_(mainloop) ;(---------Puts out the strings represented by F keys-----------) ;|When you press a F key, these are run, putting out the data | ;|Input: none | ;|Output: puts string in sendoutbuffer and dispoutbuffer if nec.| ;(--------------------------------------------------------------) putF1: ld a,0 CALL_(sendfunction) JUMP_(mainloop) putF2: ld a,22 CALL_(sendfunction) JUMP_(mainloop) putF3: ld a,44 CALL_(sendfunction) JUMP_(mainloop) putF4: ld a,66 CALL_(sendfunction) JUMP_(mainloop) putF5: ld a,88 CALL_(sendfunction) JUMP_(mainloop) ;(--------------The dirty stuff to manipulate the F keys----------) ;|Does the dirty work of figureing out the function and length | ;|and the like | ;|Input: a contains relative address from the five functions above| ;|Output: stuff put in buffers | ;(----------------------------------------------------------------) sendfunction: ld e,a ld d,0 ld hl,(PROGRAM_ADDR) add hl,de ld de,functionkeys add hl,de ld de,00021 add hl,de ld c,(hl) ld a,c ;no stuff there causes a problem cp 0 ret z ;so leave without doing anything scf ccf sbc hl,de inc hl ;bypass the 20 at the beginning push hl push bc CALL_(putinsendout) pop bc ld hl,localecho_on bit 0,(hl) pop hl jr z,sendfunction2 CALL_(putindispout) sendfunction2: ret ;(-----------------Accesses more characters---------------) ;|Pops up that menu to get an extra 20 characters | ;|Input: none | ;|Output: puts the selected character in the buffers | ;(--------------------------------------------------------) sendmorechars: im 1 CALL_(morechars) ;returns a with character cp 0 JUMP_Z(sendmorechars2) ld c,0 CALL_(putinsendout) ld c,0 ld hl,localecho_on bit 0,(hl) jr z,sendmorechars2 CALL_(putindispout) sendmorechars2: im 2 JUMP_(mainloop) ;***************************** ;*All sorts of routines for the vt100 stuff vt100time: ld hl,vt100_on ;check for vt100 bit 0,(hl) ; jr z,vt100time2 ld de,(beginbufferdata) ld hl,(buffercursor) scf ccf sbc hl,de ;hl left with length of stuff in buffer dec hl ld a,h cp 0 CALL_NZ(makelarge) ;whether it goes or not, l length of stuff ld a,l ;now a length of stuff ld hl,(PROGRAM_ADDR) ld de,vt100table add hl,de vt100time2: push af ;save the length through this loop ld b,(hl) ;cp length with length of command ld a,$FF cp b jr z,vt100timeend pop af push af sub b ;subtract to see if greater than carry will be set if so bit 7,a ;check other way <--------- JUMP_NZ(vt100time3) inc hl ld de,(beginbufferdata) ;de now caontains place in buffer inc de ;get past ESC ;hl contains vt100table b contains length push bc CALL_(checkstring) pop bc ;this is the length jr z,vt100goaddress ;hl left with pointer inc hl inc hl ld a,(hl) pop af ;now it's needed chud for the next time through the loop jr vt100time2 vt100time3: ld c,b inc c ld b,0 add hl,bc ;get it to the next command to check inc hl inc hl ;pass the pointer pop af ;get the saved length for next time through loop jr vt100time2 vt100timeend: pop af pop hl ;premature ending, (no command) get rid of return address add a,$06 ; bit 4,a jr nz,vt100warning JUMP_(mainloop) ;and go back to mainloop makelarge: ld l,$FF ret vt100warning: im 1 ld hl,$0000 ld ($800C),hl ld hl,(PROGRAM_ADDR) ld de,vt100helpmessage add hl,de ROM_CALL(D_ZT_STR) ld hl,$0001 ld ($800C),hl ld hl,(beginbufferdata) ;this points to the faulty string ld (hl),10 ;get rid of ESC, puts the length there ROM_CALL(D_LT_STR) warnkeys: call GET_KEY cp $00 jr z,warnkeys ld a,0 ld (startoverind),a JUMP_(start) ;and might as well start over from beginning vt100goaddress: pop af ;unneeded chud off stack call LD_HL_MHL ;hl is pointer to place to go ex de,hl ld hl,(PROGRAM_ADDR) add hl,de push bc ;this saves the length, so we can erase the stuff when done push hl ;put it on stack ret ;ret goes to place on stack, removes it. vt100timefinish: pop bc ;b is length from the vt100table ld c,b ld b,0 ld hl,(beginbufferdata) add hl,bc ld (beginbufferdata),hl ld a,0 ret ;****The rest of this vt100 stuff is different routines that are called from ;****above, vt100goaddress, through thew location in the table at the bottom. vt100cursorleft: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 ;unascii it ld b,a ld de,(endbuffer) ;used later ld hl,(cursoraddress) jr vt100cursorleft2 vt100cursorleftlots: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 push de ;\ ld de,00010 ; \ CALL_(mult) ; |mult first digit by ten ; / left in l pop de ;/ inc de ;\ ld a,(de) ;}add next digit sub $30 ;!!!!! unascii the stupid thing, always forget add a,l ;/ ld b,a ld de,(endbuffer) ld hl,(cursoraddress) vt100cursorleft2: call CP_HL_DE jr z, vt100cursorleft22 dec hl djnz vt100cursorleft2 vt100cursorleft22: ld (cursoraddress),hl ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100cursorright: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 ;unascii it ld b,a ld hl,00079 ld de,(endbuffer) add hl,de ld de,(cursoraddress) ex de,hl jr vt100cursorright2 vt100cursorrightlots: ld de,(beginbufferdata) ;no checking yet inc de inc de ld a,(de) sub $30 push de ;\ ld de,00010 ; \ CALL_(mult) ; |mult first digit by ten ; / left in l pop de ;/ inc de ;\ ld a,(de) ;}add next digit sub $30 ;!!!!! unascii the stupid thing, always forget add a,l ;/ ld b,a ld de,(endbuffer) ld hl,00079 add hl,de ex de,hl ld hl,(cursoraddress) vt100cursorright2: call CP_HL_DE jr z, vt100cursorright22 inc hl djnz vt100cursorright2 vt100cursorright22: ld (cursoraddress),hl ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100cursorup: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 ;unascii it ld b,a ld de,(startbuffer) ld hl,(endbuffer) ld ix,$0000 jr vt100cursorup2 vt100cursoruplots: ld de,(beginbufferdata) ;no checking yet inc de inc de ld a,(de) sub $30 push de ;\ ld de,00010 ; \ CALL_(mult) ; |mult first digit by ten ; / left in l pop de ;/ inc de ;\ ld a,(de) ;}add next digit sub $30 ;!!!!! unascii the stupid thing, always forget add a,l ;/ ld b,a ld de,(startbuffer) ld hl,(endbuffer) ld ix,$0000 vt100cursorup2: call CP_HL_DE jr z,vt100cursorup22 push bc ld bc,00080 scf ccf sbc hl,bc add ix,bc pop bc djnz vt100cursorup2 vt100cursorup22: ld (endbuffer),hl push ix pop bc ld hl,(cursoraddress) sbc hl,bc ld (cursoraddress),hl ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100cursordown: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 ;unascii it ld b,a jr vt100cursordown2 vt100cursordownlots: ld de,(beginbufferdata) inc de inc de ld a,(de) sub $30 push de ;\ ld de,00010 ; \ CALL_(mult) ; |mult first digit by ten ; / left in l pop de ;/ inc de ;\ ld a,(de) ;}add next digit sub $30 ;!!!!! unascii the stupid thing, always forget add a,l ;/ ld b,a vt100cursordown2: ;do I need the table??? ld hl,(PROGRAM_ADDR) ;check later ld de,lflftable add hl,de ld c,b CALL_(putindispout) JUMP_(vt100timefinish) vt100storecoords: ld hl,(cursoraddress) ld (storedcoords),hl ld hl,(endbuffer) ld (storedline),hl JUMP_(vt100timefinish) vt100restorecoords: ld hl,(storedcoords) ld (cursoraddress),hl ld hl,(storedline) ld (endbuffer),hl ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100index: ld a,$0A ld c,0 CALL_(putindispout) JUMP_(vt100timefinish) vt100reverseindex: ld hl,(startbuffer) ex de,hl ld hl,(endbuffer) call CP_HL_DE jr z,vt100reverseindex2 ld bc,00080 scf ccf sbc hl,bc ld (endbuffer),hl ld hl,(cursoraddress) sbc hl,bc ld (cursoraddress),hl ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100reverseindex2: ld de,(startbuffer) ld hl,(memend) scf ccf sbc hl,de push hl ;amount for lddr ld hl,(memend) ld de,(memend) ld bc,00080 add hl,bc dec hl dec de ex de,hl ;hl = lower one move from de = higher one move to pop bc lddr ld hl,(startbuffer) ld de,(startbuffer) inc de ld (hl),0 ld bc,00079 ldir CALL_(clearscreen) ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100nextline: ld hl,(PROGRAM_ADDR) ld de,crlftable add hl,de ld c,2 CALL_(putindispout) JUMP_(vt100timefinish) vt100eraseline: ld hl,(endbuffer) ld bc,00079 ld de,(endbuffer) inc de ld (hl),$20 ldir ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100eraseendline: ld hl,(endbuffer) ld bc,00080 add hl,bc ex de,hl ld hl,(cursoraddress) vt100eraseendline2: call CP_HL_DE jr z,vt100eraseendline3 ld (hl),$20 inc hl jr vt100eraseendline2 vt100eraseendline3: ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100erasecursor: ld hl,(endbuffer) ld de,(cursoraddress) vt100erasecursor2: ld (hl),$20 call CP_HL_DE jr z,vt100erasecursor3 inc hl jr vt100erasecursor2 vt100erasecursor3: ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100cursorstyle: ld hl,vt100charattrib ld de,(beginbufferdata) inc de vt100cursorstyle2: inc de ld a,(de) cp 59 ;equal to jr z,vt100cursorstyle2 cp 'm' JUMP_Z(vt100timefinish) cp '0' jr z,vtcursorstylenone cp '1' jr z,vtcursorstylebold cp '4' jr z,vtcursorstyle_score cp '5' jr z,vtcursorstyleblink cp '7' jr z,vtcursorstylereverse JUMP_(vt100timefinish) vtcursorstylenone: ld (hl),0 ;hl is vt100charattrib jr vt100cursorstyle2 vtcursorstylebold: set 0,(hl) ;bit 0 of hl is for bold jr vt100cursorstyle2 vtcursorstyle_score: set 1,(hl) jr vt100cursorstyle2 vtcursorstyleblink: set 2,(hl) jr vt100cursorstyle2 vtcursorstylereverse: set 3,(hl) jr vt100cursorstyle2 vt100settab: ld hl,(cursoraddress) ld de,(endbuffer) scf ccf sbc hl,de push hl ld c,l ld a,h ld de,00008 CALL_(div) ;bytes to move in c pop hl ld a,l and $07 inc a ld b,a ;byte counter to go through ld a,0 scf vt100settab2: rra ;%00000000 +C(1) rotate right djnz vt100settab2 ld b,0 ;c is still untouched ld hl,(PROGRAM_ADDR) ld de,tabtable add hl,de add hl,bc ;place to add new tab or (hl) ;hl contains pointer to tabtable, a contains new tab ld (hl),a ;new tab has been put JUMP_(vt100timefinish) vt100cleartab: ld hl,(cursoraddress) ld de,(endbuffer) scf ccf sbc hl,de push hl ld c,l ld a,h ld de,00008 CALL_(div) pop hl ld a,l and $07 inc a ld b,a ld a,0 scf vt100cleartab2: rra djnz vt100cleartab2 ld b,0 ld hl,(PROGRAM_ADDR) ld de,tabtable add hl,de add hl,bc cpl and (hl) ld (hl),a JUMP_(vt100timefinish) vt100clearalltabs: ld hl,(PROGRAM_ADDR) ld de,tabtable add hl,de ld b,10 clearalltabsloop: ld (hl),0 inc hl djnz clearalltabsloop dec hl set 0,(hl) JUMP_(vt100timefinish) vt100statusrep: ld hl,(PROGRAM_ADDR) ld de,statusgood add hl,de ld c,4 ;length CALL_(putinsendout) JUMP_(vt100timefinish) vt100whatareyou: ld hl,(PROGRAM_ADDR) ld de,whatareyou add hl,de ld c,7 CALL_(putinsendout) JUMP_(vt100timefinish) vt100cursorreport: ld ix,00006 ld hl,(endbuffer) ;throughout whole routine, ix contains counter ld de,(firstline) scf ccf sbc hl,de ld a,h ld c,l ld de,00080 CALL_(div) ;out in ac ld a,c inc a ld hl,(PROGRAM_ADDR) ld de,cursorresponse add hl,de inc hl inc hl CALL_(putasciivalue) ld (hl),59 ;this is ; inc hl push hl ld hl,(cursoraddress) ld de,(endbuffer) scf ccf sbc hl,de ld a,l inc a pop hl ;from stack after last putasciivalue CALL_(putasciivalue) ld (hl),82 ;this is R ld hl,(PROGRAM_ADDR) ld de,cursorresponse add hl,de push ix pop bc CALL_(putinsendout) JUMP_(vt100timefinish) putasciivalue: ;asciiizes the value in a and put it in the place pointed to ;by hl(cursorresponse) push af ld c,a ld a,0 ld de,00010 ;divide by 10 push hl CALL_(div) ;ac/de=ac pop hl cp c ;a will definitely be 0, because the most in ac would be 8 ;so this will see if c is zero jr nz,putasciivalue2 pop af add a,$30 ld (hl),a inc hl ret putasciivalue2: inc ix pop af push hl ld l,a ld h,0 call UNPACK_HL add a,$30 ld b,a call UNPACK_HL add a,$30 pop hl ld (hl),a inc hl ld (hl),b inc hl ret vt100reset: ;this is a hard reset, so I checked how many pushes pop hl ;there were, get them out first pop hl im 1 ;always redo this when add new stuff!!!!!!! ld a,1 ld (startoverind),a JUMP_(start) vt100changecursor: ld de,(beginbufferdata) inc de inc de CALL_(vt100changesmall) ld b,a inc de inc de CALL_(vt100changesmall) ld c,a ;row in b, column in c jr vt100changecur2 vt100changeud: ;for cursor-up-down ld de,(beginbufferdata) inc de inc de CALL_(vt100changebig) ld b,a ;don't need 'push bc's' because don't have changebig later inc de inc de CALL_(vt100changesmall) ld c,a jr vt100changecur2 vt100changelr: ld de,(beginbufferdata) inc de inc de CALL_(vt100changesmall) ld b,a push bc inc de inc de CALL_(vt100changebig) pop bc ld c,a jr vt100changecur2 vt100changeudlr: ld de,(beginbufferdata) inc de inc de CALL_(vt100changebig) ld b,a push bc inc de inc de CALL_(vt100changebig) pop bc ld c,a jr vt100changecur2 vt100changebig: ld a,(de) sub $30 push de ld de,00010 CALL_(mult) pop de inc de ld a,(de) sub $30 add a,l ret vt100changesmall: ld a,(de) sub $30 ret vt100changecur2: ld a,20 sub b CALL_C(vt100changefit) ld a,b dec a ld de,00080 CALL_(mult) ;hl gives it out ld de,(firstline) add hl,de ld (endbuffer),hl ld a,80 sub c CALL_C(vt100changefit2) ld b,0 ;c with column dec c ;so starts on zero add hl,bc ld (cursoraddress),hl ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100changefit: ld b,20 ret vt100changefit2: ;add this soon ld c,1 ret vt100entirescreen: ld hl,(firstline) ld bc,01599 push hl pop de inc de ld a,0 ld (hl),a ldir CALL_(clearscreen) ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100erasebegcursor: ld de,(firstline) ld hl,(cursoraddress) scf ccf sbc hl,de push hl pop bc ld hl,(firstline) push hl pop de inc de ld a,0 ld (hl),a ldir CALL_(clearscreen) ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100erasecursorend: ld hl,(lastline) ld de,00079 add hl,de ld de,(cursoraddress) scf ccf sbc hl,de push hl pop bc ld hl,(cursoraddress) push hl pop de inc de ld a,0 ld (hl),a ldir CALL_(clearscreen) ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(displayscreen) JUMP_(vt100timefinish) vt100setscrolling: ld de,(beginbufferdata) inc de inc de CALL_(scrollingsmall) ld (firstscroll),hl inc de CALL_(scrollingsmall) ld (lastscroll),hl JUMP_(vt100timefinish) vt100setscrollingt: ld de,(beginbufferdata) inc de inc de CALL_(scrollingbig) ld (firstscroll),hl inc de CALL_(scrollingsmall) ld (lastscroll),hl JUMP_(vt100timefinish) vt100setscrollingb: ld de,(beginbufferdata) inc de inc de CALL_(scrollingsmall) ld (firstscroll),hl inc de CALL_(scrollingbig) ld (lastscroll),hl JUMP_(vt100timefinish) vt100setscrollingtb: ld de,(beginbufferdata) inc de inc de CALL_(scrollingbig) ld (firstscroll),hl inc de CALL_(scrollingbig) ld (lastscroll),hl JUMP_(vt100timefinish) scrollingsmall: ld a,(de) push de dec a sub $30 ld de,00080 CALL_(mult) ld de,(firstline) add hl,de pop de inc de ret scrollingbig: ld a,(de) push de sub $30 ld de,00010 CALL_(mult) pop de inc de push de ld a,(de) sub $30 add a,l dec a ld de,00080 CALL_(mult) ld de,(firstline) add hl,de pop de inc de ret ;(---------------------Scrolls the desired direction----------------------) ;|These four routines are jumped to from the main key loop, and do their | ;|thing on the screen, then jump back to the beginning of mainloop | ;|Input: nothing | ;|Output: moves the screen the desired direction | ;(------------------------------------------------------------------------) scrollright: ld a,(displaycolumn) cp 60 JUMP_Z(mainloop) ld b,6 add a,b ld (displaycolumn),a ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) JUMP_(mainloop) scrollleft: ld a,(displaycolumn) cp 0 JUMP_Z(mainloop) ld b,-6 add a,b ld (displaycolumn),a ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) JUMP_(mainloop) scrolldown: ld hl,(realendbuffer) ld de,00720 scf ccf sbc hl,de ld de,(displaystart) ex de,hl call CP_HL_DE JUMP_Z(mainloop) ld de,$0050 add hl,de ld (displaystart),hl ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) JUMP_(mainloop) scrollup: ld hl,(displaystart) ld de,(startbuffer) call CP_HL_DE JUMP_Z(mainloop) ld de,$0050 sbc hl,de ld (displaystart),hl ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) JUMP_(mainloop) ;(-----------------------Exit routine-----------------------------------) ;|This routine is jumped to and exits the program, first clearing the | ;|memory that was overwritten | ;|Input: nothing | ;|Output: goes back to title | ;(----------------------------------------------------------------------) timetogo: im 1 ld a,0 ld (startoverind),a JUMP_(start) ;(------------------Get more chars from the menu--------------------------) ;|This routine lets you pick one of the 20 characters not accesible on the| ;|TI-85 keyboard. It saves the bottom portion of the screen it writes | ;|over, and then restores it when done. | ;|Input: nothing | ;|Output: a has character from menu, 0 if none | ;(------------------------------------------------------------------------) morechars: CALL_(savebottom) ld hl,(PROGRAM_ADDR) ld de,chartable add hl,de ld (currentmenu),hl CALL_(dispmenu) morechars2: CALL_(recievebyte) ;this is the routine to cp 0 CALL_NZ(putindatabuffer) call GET_KEY cp K_MORE jr z,changemenu cp K_F1 JUMP_Z(takeF1) cp K_F2 JUMP_Z(takeF2) cp K_F3 JUMP_Z(takeF3) cp K_F4 JUMP_Z(takeF4) cp K_F5 JUMP_Z(takeF5) cp K_EXIT jr nz,morechars2 ld a,0 ;didn't get any char morechars3: CALL_(restorebottom) ret ;(--------------All part of the previous subroutine--------) changemenu: ld hl,(PROGRAM_ADDR) ld de,chartable4 add hl,de ex de,hl ld hl,(currentmenu) call CP_HL_DE jr z,changemenu2 ld bc,00022 add hl,bc JUMP_(changemenu3) changemenu2: ld hl,(PROGRAM_ADDR) ld de,chartable add hl,de changemenu3: ld (currentmenu),hl CALL_(dispmenu) JUMP_(morechars2) ;(--------------All part of the previous subroutine--------) takeF1: ld a,1 jr takeitaway takeF2: ld a,5 jr takeitaway takeF3: ld a,9 jr takeitaway takeF4: ld a,13 jr takeitaway takeF5: ld a,17 jr takeitaway takeitaway: ld hl,(currentmenu) ld c,a ld b,0 add hl,bc ld a,(hl) ;the char is in a JUMP_(morechars3) ;(--------------All part of the previous subroutine--------) dispmenu: CALL_(clearbottom) CALL_(displaymenu) ld a,58 ld ($8334),a ld hl,(currentmenu) ld b,5 dispmenu2: ld a,(hl) ld ($8333),a inc hl inc hl ROM_CALL(D_ZM_STR) djnz dispmenu2 ret ;(---------------Display the preferences screen-------------) ;|Displays the screen, does all the work, changes things | ;|lets you change function keys | ;|Input: none | ;|Output: changes the preferences, duhh... | ;(----------------------------------------------------------) termprefs: im 1 CALL_(clearscreen) ld de,$0500 ld ($800C),de ld hl,(PROGRAM_ADDR) ld de,prefwords add hl,de set 3,(IY+05) ROM_CALL(D_ZT_STR) res 3,(IY+05) ld de,$0002 ld ($800C),de ld a,8 prefsloop: ROM_CALL(D_ZT_STR) inc e ld ($800C),de cp e jr nz,prefsloop ld hl,vt100_on ld de,$0102 ld ($800C),de ld a,7 prefsloop2: bit 0,(hl) CALL_NZ(option_on) inc hl inc e ld ($800C),de cp e jr nz,prefsloop2 ld hl,vt100_on ld (currentpref),hl ld hl,$0002 ld ($800C),hl ld a,5 ROM_CALL(TR_CHARPUT) jr keytime option_on: push af ld a,0 ROM_CALL(TR_CHARPUT) pop af ret ;(--------------All part of the previous subroutine--------) keytime: CALL_(recievebyte) ;this is the routine to cp 0 CALL_NZ(putindatabuffer) call GET_KEY cp K_DOWN jr z,downprefs cp K_UP jr z,upprefs cp K_SECOND JUMP_Z(changepref) cp K_EXIT jr nz,keytime go_from_prefs: ;last piece of code before returns ld hl,(PROGRAM_ADDR) ld de,savedprefs add hl,de ld de,vt100_on ex de,hl ld bc,00005 ldir CALL_(clearscreen) ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(displayscreen) im 2 JUMP_(mainloop) ;(--------------All part of the previous subroutine--------) downprefs: ld hl,(currentpref) ld de,splitscreen_on+1 call CP_HL_DE jr z,keytime inc hl ld (currentpref),hl ld a,$20 ROM_CALL(TR_CHARPUT) ld hl,($800C) inc l ld ($800C),hl push hl ld a,5 ROM_CALL(TR_CHARPUT) pop hl ld ($800C),hl JUMP_(keytime) upprefs: ld hl,(currentpref) ld de,vt100_on call CP_HL_DE JUMP_Z(keytime) dec hl ld (currentpref),hl ld a,$20 ROM_CALL(TR_CHARPUT) ld hl,($800C) dec l ld ($800C),hl push hl ld a,5 ROM_CALL(TR_CHARPUT) pop hl ld ($800C),hl JUMP_(keytime) ;(--------------All part of the previous subroutine--------) changepref: ld hl,(currentpref) ld c,l ld b,h ld de,vt100_on ld a,l sub e ;a now equals 0-5 ld hl,absnovt100 sub (hl) ;subtract this indicator from a JUMP_C(keytime) ;a was zero before, which means it's on vt100 ;if one was subtracted, that means NO VT100 allowed, which means ;went past 0, which set carry flag, so jump ld l,c ld h,b ld de,splitscreen_on+1 call CP_HL_DE jr z,setfunctionkeys bit 0,(hl) jr z,turnon jr turnoff changepref2: ROM_CALL(TR_CHARPUT) dec h ld ($800C),hl JUMP_(keytime) turnoff: res 0,(hl) ld hl,($800C) inc h ld ($800C),hl ld a,$20 JUMP_(changepref2) turnon: set 0,(hl) ld hl,($800C) inc h ld ($800C),hl ld a,0 JUMP_(changepref2) ;(----------------Lets you change functionkeys----------) ;|Changes screen, enters them, morechars, del | ;|Input: none | ;|Output: changes the function keys if changed | ;(------------------------------------------------------) setfunctionkeys: CALL_(dispfunctionkeys) setkeyloop: CALL_(recievebyte) ;this is the routine to cp 0 CALL_NZ(putindatabuffer) call GET_KEY cp K_EXIT JUMP_Z(go_from_prefs) cp K_F1 JUMP_Z(changeF1) cp K_F2 JUMP_Z(changeF2) cp K_F3 JUMP_Z(changeF3) cp K_F4 JUMP_Z(changeF4) cp K_F5 JUMP_Z(changeF5) jr setkeyloop ;(--------------All part of the previous subroutine--------) ;(----------------Displays the screen for it---------------) dispfunctionkeys: CALL_(clearscreen) ld hl,$0400 ld ($800C),hl ld hl,(PROGRAM_ADDR) ld de,funckeywords add hl,de set 3,(IY+05) ROM_CALL(D_ZT_STR) ld hl,$0002 ld ($800C),hl ld a,'1' ld b,5 dispnumbers: ROM_CALL(TR_CHARPUT) inc a inc l ld ($800C),hl djnz dispnumbers res 3,(IY+05) ld hl,$0102 ld ($800C),hl ld hl,(PROGRAM_ADDR) ld de,functionkeys add hl,de ld b,5 dispwords: push bc ROM_CALL(D_LT_STR) pop bc inc hl ;get pst the lentgh terminator at end push hl ld hl,($800C) inc h ld ($800C),hl pop hl djnz dispwords ld hl,$0007 ld ($800C),hl ld hl,(PROGRAM_ADDR) ld de,funckeywords2 add hl,de ROM_CALL(D_ZT_STR) ret ;(--------------All part of the previous subroutine--------) changeF1: ld a,0 jr changeFkeys changeF2: ld a,22 jr changeFkeys changeF3: ld a,44 jr changeFkeys changeF4: ld a,66 jr changeFkeys changeF5: ld a,88 jr changeFkeys changeFkeys: ld hl,(cursorstate) ld e,l ld l,h ld h,e ld (cursorstate),hl CALL_(enternewfunc) ld hl,(cursorstate) ld e,l ld l,h ld h,e ld (cursorstate),hl JUMP_(setfunctionkeys) ;(--------------All part of the previous subroutine--------) ;|This deals with after the beginning screen, and you've | ;|picked the function to edit | ;(---------------------------------------------------------) enternewfunc: CALL_(clearscreen) ld hl,(PROGRAM_ADDR) ld de,functionkeys add hl,de ld e,a ld d,0 add hl,de ld (Fkeyaddress),hl ld a,0 ld (Fkeycursor),a ld hl,$0000 ld ($800C),hl ld hl,(Fkeyaddress) ROM_CALL(D_LT_STR) ld hl,$0101 ld ($800C),hl ld hl,(PROGRAM_ADDR) ld de,funckeywords3 add hl,de ROM_CALL(D_ZT_STR) ld hl,(Fkeyaddress) inc hl ;this bypasses the 20 at the brginning ld b,20 clearlooper: ld (hl),$20 inc hl djnz clearlooper Fkeykeyloop: CALL_(recievebyte) ;this is the routine to cp 0 CALL_NZ(putindatabuffer) call GET_KEY cp K_EXIT JUMP_Z(Fkeyenterdone) cp K_MORE JUMP_Z(Fkeymorechars) cp K_DEL JUMP_Z(Fkeydel) cp K_ENTER JUMP_Z(Fkeyenterdone) cp 0 JUMP_NZ(Fkeyfigure) jr Fkeykeyloop ;(--------------All part of the previous subroutine--------) Fkeyenterdone: ld hl,(Fkeyaddress) ld de,00021 add hl,de ld a,(Fkeycursor) ld (hl),a ret Fkeyfigure: ld l,a ld a,(cursorstate) cp $02 CALL_Z(bigalphamode) cp $03 CALL_Z(smallalphamode) cp $00 CALL_Z(normmode) cp $01 CALL_Z(secondmode) ld a,l ;all the modes return the value in l cp 0 JUMP_Z(Fkeyfigure2) CALL_(loadFkeychar) Fkeyfigure2: JUMP_(Fkeykeyloop) Fkeymorechars: CALL_(morechars) cp 0 CALL_NZ(loadFkeychar) JUMP_(Fkeykeyloop) Fkeydel: ld a,(Fkeycursor) cp 0 JUMP_Z(Fkeykeyloop) dec a ld (Fkeycursor),a ld a,$20 CALL_(loadFkeychar) ld a,(Fkeycursor) dec a ld (Fkeycursor),a JUMP_(Fkeykeyloop) ;(--------------All part of the previous subroutine--------) loadFkeychar: push af ld a,(Fkeycursor) cp 20 jr z,loadFkeychar2 ld e,a ld d,0 ld hl,(Fkeyaddress) inc hl add hl,de pop af push af ld (hl),a ld a,(Fkeycursor) ld ($800D),a ld a,2 ld ($800C),a pop af ROM_CALL(TX_CHARPUT) ld a,(Fkeycursor) inc a ld (Fkeycursor),a ret loadFkeychar2: pop af ret ;(-------------Routine to get two special keys from keyboard-----------) ;|Gets enterkey and del key and does the necessary stuff | ;|Input: none | ;|Output: stuff put in buffers | ;(---------------------------------------------------------------------) enterkey: ld a,(outboundCRLF_on) ;0 if want CR 1 if want CR/LF inc a ;this is the length ld c,a ld hl,(PROGRAM_ADDR) ld de,crlftable add hl,de push hl CALL_(putinsendout) ld hl,localecho_on bit 0,(hl) pop hl jr z,enterkey2 ld c,a ;a is still okay CALL_(putindispout) enterkey2: JUMP_(mainloop) delkey: ld a,$08 ld c,0 CALL_(putinsendout) ld c,0 ld hl,localecho_on bit 0,(hl) jr z,delkey2 CALL_(putindispout) delkey2: JUMP_(mainloop) ;***************************************** ;****Figure is called to convert the keypress ;****into correct ASCII character, based on ;****(cursorstate), and keypress in A. Sends ;****it if neccesary, and outputs it if neccesary. ;****Only used in the terminal screen, not function keys ;************************************************* figure: ld l,a ld a,(cursorstate) cp $02 CALL_Z(bigalphamode) cp $03 CALL_Z(smallalphamode) cp $00 CALL_Z(normmode) cp $01 CALL_Z(secondmode) ld a,l ;all the modes return the value in l cp 0 JUMP_Z(figure2) ld c,0 CALL_(putinsendout) ld c,0 ld hl,localecho_on bit 0,(hl) jr z,figure2 CALL_(putindispout) figure2: JUMP_(mainloop) ;++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++Called when key is pressed during time when ;++++cursor is on BIG alpha KEY IN L, SAVES AF ;++++++++++++++++++++++++++++++++++++++++++++++++++ bigalphamode: push af ld a,l cp K_ALPHA CALL_Z(cursornorm) cp K_SECOND CALL_Z(cursor2nd) ld de,bigalphatable CALL_(convertkey) ld l,a pop af ret bigalphatable: .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,"XTOJE",$00 .db $00,$20,"WSNID",$00,$00,"ZVRMHC",$00 .db $00,"YUQLGB",$00,$00,$00,"=PKFA",$00 .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++Called when key is pressed during time when ;++++cursor is on norm cursor ;++++++++++++++++++++++++++++++++++++++++++++++++++ normmode: push af ld a,l cp K_ALPHA CALL_Z(cursorbigalpha) cp K_SECOND CALL_Z(cursor2nd) ld de,normtable CALL_(convertkey) ld l,a pop af ret normtable: .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,"+-*/^",$00 .db $00,$00,"369)",$00,$00,$00,".258(",$00,$00 .db $00,"0147",$00,$00,$00,$00,$00,$00,",",$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$00,$00,$00 ;++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++Called when key is pressed during time when ;++++cursor is on small alpha ;++++++++++++++++++++++++++++++++++++++++++++++++++ smallalphamode: push af ld a,l cp K_ALPHA CALL_Z(cursornorm) cp K_SECOND CALL_Z(cursor2nd) ld de,smallalphatable CALL_(convertkey) ld l,a pop af ret smallalphatable: .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,"xtoje",$00 .db $00,$20,"wsnid",$00,$00,"zvrmhc",$00 .db $00,"yuqlgb",$00,$00,$00,"=pkfa",$00 .db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++Called when key is pressed during time when ;++++cursor is on 2nd cursor ;++++++++++++++++++++++++++++++++++++++++++++++++++ secondmode: push af ld a,l cp K_ALPHA CALL_Z(cursorsmallalpha) cp K_SECOND CALL_Z(cursornorm) cp K_LEFTPAR JUMP_Z(leftbracket) cp K_RIGHTPAR JUMP_Z(rightbracket) cp K_DOT JUMP_Z(twodots) ld a,0 secondmode2: ld l,a pop af ret leftbracket: ld a,'[' JUMP_(secondmode2) rightbracket: ld a,']' JUMP_(secondmode2) twodots: ld a,':' JUMP_(secondmode2) ;******************************************* ;****Converts scancode in a to correct TI-ascii character ;****according to the table address in de, if nothing ;****goes back to beginning loop ;******************************************* convertkey: ld hl,(PROGRAM_ADDR) add hl,de ld d,0 ld e,a add hl,de ld a,(hl) ret ;************************************************* ;****Puts character in buffer ;************************************************* charinbuffer: cp $0D ;a holds char, see if it is a carriagereturn JUMP_Z(loadcr) ;goto this special place cp $0A JUMP_Z(loadlf) cp $0B JUMP_Z(loadlf) cp $0C JUMP_Z(loadlf) cp $07 JUMP_Z(loadbell) cp $09 JUMP_Z(loadtab) cp $08 JUMP_Z(loadbkspce) ld hl,vt100charattrib bit 3,(hl) CALL_NZ(makereverse) ld hl,(cursoraddress) ld (hl),a ;if that went all fine, just load char into buffer inc hl ;incs the cursoraddress to the next position ld (cursoraddress),hl ;loads it back ld de,(endbuffer) ld bc,$0050 ex de,hl add hl,bc call CP_HL_DE JUMP_Z(increasebuffer) ld hl,(cursorcoords) ld de,$FFFF call CP_HL_DE jr nz,simpleput ld hl,(cursoraddress) push hl ld hl,(endbuffer) ld a,(displaycolumn) ld e,a ld d,0 add hl,de pop de ;de is cursoraddress, hl is displaycolumn scf ccf ;makes sure carry flag is off sbc hl,de rlc h JUMP_C(noput) ld hl,(endbuffer) ;gets the endbuffer, because that's what we want to display ld (currrow),hl ;currrow is the first line to display ld a,1 ;and we just want that line ld (linestodisplay),a ;into there CALL_(displayscreen) ;and display the stuff ret ;go back makereverse: set 7,a ret simpleput: ld hl,(cursorcoords) ld ($8333),hl res 7,a ROM_CALL(M_CHARPUT) ld hl,($8333) ld a,6 add a,l bit 7,a jr nz,cursornomore ld (cursorcoords),hl ret cursornomore: ld hl,$FFFF ld (cursorcoords),hl ret noput: ret increasebuffer: ld hl,(endbuffer) ld de,(lastscroll) call CP_HL_DE ;sees if endbuffer is equal to lastscroll before changing endbuffer JUMP_Z(scrollstuff) ld hl,(endbuffer) ld bc,00080 add hl,bc ;this does the simple increasing of (endbuffer) ld (endbuffer),hl ;hl equals the endbuffer+80, to increase the buffer ld de,(realendbuffer) ;\ scf ;\This sees if endbuffer has passed realendbuffer ccf ;\and then increases realendbuffer and lastline ex de,hl ;/if it is. remember, realendbuffer=lastline sbc hl,de ;/ CALL_C(increaserealend) ;/ ld hl,(endbuffer) ;\ ld de,(memend) ; \this sees if the mem is at the end of the VAT call CP_HL_DE ; /goes to reached_end if so to move it CALL_Z(reached_end) ;/ ld hl,(endbuffer) ;\ ld de,(displaystart) ; \ scf ; \ This sees if the new line goes past the screen, ccf ; \and if so, then changes displaystart and redisplays sbc hl,de ; /the screen ld de,00800 ; / call CP_HL_DE ; / JUMP_Z(movescreen) ;/ ld hl,(endbuffer) ;\ scf ; \ ccf ; \ This displays two lines, the previous line and the sbc hl,bc ; \current line ld (currrow),hl ; / ld a,2 ; / and then returns ld (linestodisplay),a ; / CALL_(displayscreen) ;/ ret increaserealend: ld hl,(endbuffer) ;increases realendbuffer and lastline, which are equal ld (realendbuffer),hl ;in value, but not in definition ld (lastline),hl CALL_(makefirstline) ;this finds firstline from lastline, and loads it ret movescreen: ld bc,00080 ;80 ld hl,(displaystart) ;takes displaystart add hl,bc ;adds 80 ld (displaystart),hl ;and loads it back ld (currrow),hl ;dispalys the whole screen again ld a,10 ;\/ ld (linestodisplay),a ;\/ CALL_(clearscreen) ;\/ CALL_(displayscreen) ;\/ ret ;return scrollstuff: ld hl,(firstscroll) ;de is still lastscroll ex de,hl ;sub lastscroll from firstscroll - scf ccf sbc hl,de ;this finds size of stuff to move push hl ;puts the amount on stack later to be put in bc ld hl,(firstscroll) ld bc,00080 add hl,bc ;the source ld de,(firstscroll) ;the destination pop bc ;the length ldir ld hl,(lastscroll) ;these next few lines clear the last line with zeros ld bc,00079 push hl pop de inc de ld a,0 ld (hl),a ldir ld hl,(endbuffer) ld (cursoraddress),hl ld hl,(displaystart) ld (currrow),hl ld a,10 ld (linestodisplay),a CALL_(clearscreen) CALL_(displayscreen) ret ;big return back to whereever reached_end: ;pretty much changes all the variables ld hl,(startbuffer) ;after moving everything down, should seem unknown ld bc,00080 ;to rest of the program add hl,bc ld de,(memend) ex de,hl scf ccf sbc hl,de ld b,h ld c,l ld hl,(startbuffer) ex de,hl ldir ;bc is byte counter(memend-startbuffer+80) ;hl is startbuffer+80 ;de is startbuffer inc de push de pop hl inc de ld (hl),0 ld bc,00079 ldir ld bc,00080 ld hl,(displaystart) scf ;you don't need these later because it's all loads ccf ;and they don't do anything to the carrry flag sbc hl,bc ld (displaystart),hl ld hl,(endbuffer) sbc hl,bc ld (endbuffer),hl ld (realendbuffer),hl ;change this too ld (lastline),hl CALL_(makefirstline) ld hl,(cursoraddress) sbc hl,bc ld (cursoraddress),hl ld hl,(firstscroll) sbc hl,bc ld (firstscroll),hl ld hl,(lastscroll) sbc hl,bc ld (lastscroll),hl ld hl,(storedcoords) sbc hl,bc ld (storedcoords),hl ld hl,(storedline) sbc hl,bc ld (storedline),hl ret loadcr: ld hl,(endbuffer) ld (cursoraddress),hl ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) ret loadlf: ld bc,$0050 ld hl,(cursoraddress) add hl,bc ld (cursoraddress),hl JUMP_(increasebuffer) ;this will increase endbuffer loadtab: ld hl,(endbuffer) ld bc,00080 add hl,bc ex de,hl ld hl,(cursoraddress) inc hl ;incs cursoraddress call CP_HL_DE ;if it is at the last byte of line ret z ;go back cause tab don't work there dec hl ;dec it back to normal ld bc,(endbuffer) scf ccf sbc hl,bc ld c,l ;c=column ld hl,(PROGRAM_ADDR) ld de,tabtable add hl,de ;hl=tabtable ex de,hl ;de=tabtable loadtab2: push de ;at the start, de is tabtable ld hl,(cursoraddress) inc hl ;inc place to put ld (cursoraddress),hl pop hl ;this puts tabtable in hl inc c ;and inc column ld a,c ;put in a to do bit manipultaion and $07 ;this performs a mod(a,7) xor $07 ;this reverses it 7=0;6=1 inc a ;stead of 0-7, it's 1-8 ld b,a ;b is byte counter ld a,%10000000 multsimple: rlc a ;mults %0.1 with %2 b number of times djnz multsimple ;a is left with correct bit number after push bc srl c ;divides c by 8 to get byte srl c srl c ;b is left 0 from djnz ;so bc is amount tomove. while a still has bit add hl,bc ;hl=corrected table pop bc and (hl) jr z,loadtab2 ld hl,(endbuffer) ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) ret ;de=tabtable ;bc=column c only actual equals it loadbkspce: ld de,(endbuffer) ld hl,(cursoraddress) call CP_HL_DE ret z dec hl ld (cursoraddress),hl ex de,hl ld (currrow),hl ld a,1 ld (linestodisplay),a CALL_(displayscreen) ret loadbell: ld a,$18 ld (bellcounter),a ld hl,(PROGRAM_ADDR) ld de,bellpic add hl,de ld de,$FFCF ex de,hl ld b,4 loadbell2: push bc ld bc,$0010 ld a,(de) or (hl) ld (hl),a add hl,bc inc de pop bc djnz loadbell2 ret ;*************************************** makefirstline: ;finds firstline from lastline ld hl,(lastline) ld de,01520 scf ccf sbc hl,de ld (firstline),hl ret ;++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;++++Changes the cursor from white to the ;++++current mode when called to on current ;++++coordinates at ($8333) and ($8334) ;++++++++++++++++++++++++++++++++++++++++++++++++++++++ putcursor: ld de,(cursorcoords) ld hl,$FFFF call CP_HL_DE ret z ld ($8333),de ld a,$00 ld (cursorcount),a ld hl,(state1) ld a,l ld l,h ld h,a ld (state1),hl ROM_CALL(M_CHARPUT) ret ;+++++++++++++++++++++++++++++++++++++++++++++ ;++++Routines to change cursor from ;++++various states ;+++++++++++++++++++++++++++++++++++++++++++++ cursorbigalpha: push af ld a,$02 ld (cursorstate),a pop af ret cursorsmallalpha: push af ld a,$03 ld (cursorstate),a pop af ret cursornorm: push af ld a,$00 ld (cursorstate),a pop af ret cursor2nd: push af ld a,$01 ld (cursorstate),a pop af ret ;************************************************* ;****Routine to clear the screen, the same as ;****ROM_CALL(CLEARLCD), but I think it's faster, ;****and it doesn't have to go through ZShell ;****Input = none ;****Output = clears screen ;************************************************* clearscreen: ld hl,$FC00 ld de,$FC01 ld bc,$03FF ld (hl),0 ldir ret ;************************************************* ;Routine that displays all or part of the screen, ;but does not clear it ;Input = (displaystart) = first line of screen ; (currrow) = first line to display ; (linestodisplay) = lines to display ; (displaycolumn) = column to start on ; (cursoraddress) = used to update cursorcoords ;Output = stuff displayed ; (cursorcoords) updated ; (currrow) chudded up ;************************************************* displayscreen: ;im 1 ld hl,$FFFF ld (cursorcoords),hl ld hl,(currrow) ld de,(displaystart) sbc hl,de ld a,h ld c,l ld de,$0050 CALL_(div) ;checks to see ifit is on the screen ld d,a ld e,c ld a,6 ;six pixels per line CALL_(mult) ld a,h cp 0 jr nz,skiprest ld a,l add a,4 and %11000000 cp 0 jr nz,skiprest ld a,l ld ($8334),a ld a,0 ld ($8333),a ld a,(linestodisplay) ld b,a displayscreen2: push bc CALL_(linedisplay) ld hl,(currrow) ld de,$0050 add hl,de ld (currrow),hl ld a,0 ld ($8333),a ld a,($8334) ld b,6 add a,b ld ($8334),a pop bc djnz displayscreen2 skiprest: ;im 2 ret ;***************************************** ;Routine to display one line ;called from displayscreen ;Input = (displaycolumn) ; (currrow) ; (cursoraddress) ;Output = line displayed ; (cursorcoords) updated if needed ;***************************************** linedisplay: ld hl,$0050 ;de=currrow+dispalycolumn ld de,(currrow) ;hl=cursoraddress add hl,de ;topstack=currrow+80 push hl ld a,(displaycolumn) ld l,a ld h,0 add hl,de ex de,hl ld hl,(cursoraddress) linedisplay2: call CP_HL_DE CALL_Z(setcursor) ld a,(de) cp 0 jr z,nodisplay cp $0D jr z,nodisplay cp $09 CALL_Z(disptab) push de res 7,a ROM_CALL(M_CHARPUT) pop de ld a,($8333) ld b,6 add a,b bit 7,a jr nz,finished nodisplay: inc de ex (sp),hl call CP_HL_DE jr z,finished ex (sp),hl jr linedisplay2 disptab: ld a,$20 ret dispreverse: set 3,(IY+05) ret setcursor: ld bc,($8333) ld (cursorcoords),bc ret finished: pop hl ret ;*************************************************** ;****Division routine, numerator in AC, denominator ;****in DE, answer without remainder in AC. ;****Got from Sam Davies who got it from ;****"Programming the z80 by Rodney Zaks" ;*************************************************** div: ld HL, 0 ld B, 16 and A DIVLOOP: rl C rl A rl L rl H sbc HL, DE jr nc, DIVNOADD add HL, DE DIVNOADD: ccf djnz DIVLOOP rl C rl A ret ;Multiplication Function ; Arguments: ; A = to be multiplied by DE ; DE = to be multiplied by A ; Returns: ; HL = A * DE mult: ld HL, 0 ld B, 7 srl A jr nc, SKIP_BIT0 add HL, DE jr c, MULT_OVERFLOW SKIP_BIT0: NEXT_BIT: sla E rl D jr nc, START_HERE cp 0 jr nz, MULT_OVERFLOW START_HERE: srl A jr nc, SKIP_BIT add HL, DE jr c, MULT_OVERFLOW SKIP_BIT: djnz NEXT_BIT ret MULT_OVERFLOW: scf ret ;**************************************************** ;****RecieveByte routine from ROM, comments by site@xnet.com ;****changed a little by me to allow for no byte coming in ;****and changed jp's to JUMP_'s and jr's ;**************************************************** recievebyte: ld b, $08 ; There are 8 bits to recieve ld de, $00FF ; Setup timeout counter to wait for bit ;if this de reaches 0 it is a time-out and it goes ;to an error handler ;jr WaitLoopEnd ; This jumps to the end of the loop, I have NO idea ;why this "jr" is here??? WaitLoop: in a, ($07) ; Read port 7 and $03 ; Mask the last two bits cp $00 JUMP_Z(Error) ; Cause an error if BOTH are active cp $03 ; Compare it to 11 (Both NOT active) JUMP_NZ(Continue); If at least one is active, continue. ;Notice if both were active it would have caused an ;error, so this is really only one being active in a, ($07) ; Read port 7 again and $03 ; Mask the last two bits cp $00 JUMP_Z(Error) ; I think this will cause an error if they are BOTH ;active cp $03 JUMP_NZ(Continue); Same as last time, continue if at least 1 is active dec de ; Decrease counter ld a, d or e ; or d, e JUMP_NZ(WaitLoop); If counter (de) is not 0 then loop again. JUMP_(Error) ; Cause an error if we timed out waiting for a bit Continue: sub $02 ; This is where is gets interesting. It will subtract ;10b from the accumulator (or the last two bits of ;what it received) Remember a W=1 R=0. ;So: W R ; 01 10 ; -10 (02) -10 ; ---- ---- ; 01 C 00 ;The C means the carry flag was set because the result ;was less then 0, (-1h) So now the Carry flag is set ;if we recieved a W and clear if we recieved a R. NICE JUMP_NC(Got0) ; Go to the part for receiving a 0 if we had no carry ;flag set (we got an R) Got1: ld a, $D4 ; Get ready to send a R ($D4 = Send a R, see above text) out ($07), a ; Send the W in confirmation that we recieved the bit. ;now, both wires should be pulled rr c ; This is neat. We recieved a W or a 1, because of that ;our carry flag was set. so now we are rotating that ;carry flag into the register c. So each loop will ;rotate the recieved bit into c until we have the ;complete byte. ld de, $FFFF ; Get counter ready LoopR: in a, ($07) ; Read the link and $03 ; Tell the calc to emmit radio interference cp $02 ; Is the R (and ONLY the R) active? ;The reason it does this is becasue when the sending ;85 receives the confirmation signal it will clear it's ;port, thus the W it sent will not be active when ;the port it clear. The R will be, however, because ;WE are the ones pulling it. JUMP_Z(ClearLink) dec de ; lower time-out counter ld a, d or e ; or e, d JUMP_NZ(LoopR) ; Loop until sending 85 has cleared it's side of the ;link. JUMP_(Error) ; We timed out, so cause an error. ClearLink: ld a, $C0 ; get ready to clear our side of the link out ($07), a ; Just Do It! ld d, $04 ; Get counter ready. The reason it is so low is that ;this time we aren't waiting for the other 85 to do ;anything. We are just clearing our side, so it SHOULD ;clear AS SOON as we do it. Thus the 3 loops. ClearLoop: dec d ; Lower counter JUMP_Z(NextBit) ; If we time-out it says, "oh well" and continues with ;the next loop. We can do this because if there is an ;error, it will catch it on the next bit. Note: there ;is no need for the or d, e shtuph because we are ;only dealing with the d, not de. in a, ($07) ; See a pattern? and $03 cp $03 ; Is it clear? JUMP_NZ(ClearLoop); If it's not clear, try again NextBit: ld de,$FFFF djnz WaitLoop ; Go back and do it ALL over again if B is not 0 ;i.e. we have more bits to recieve ld a, c ; We don't have any more bits to recieve, so put the ;received byte in a. ret ; and return ($C9) Got0: ld a, $E8 ; This is where we were sent if we got a R (0) ;Put E8h into a to send a confirming W out ($07), a ; Confirm rr c ; rotate the 0 (of the carry flag) into the register c ld de, $FFFF ; Get counter ready for loop LoopW: in a, ($07) ; perform a memory checksum :) and $03 ; Mask off last two bits. cp $01 ; Is ONLY the W active. (See above for indepth analysis) JUMP_Z(ClearLink); Go clear link and finish dec de ; Decrease counter ld a, d or e ; or e, d JUMP_NZ(LoopW); Keep Looping! Error: ld a,$00 ret ;jr Error ; This is where we are sent if there is an error ;(except for one time at the beg) It goes off ;somewhere in lala land. ;************************************************** ;****Send byte routine frm ROM ;************************************************** sendbyte: push af ld c, a ; This just puts the byte to send in C ld b, $0008 ; There are 8 bits to send (Seriel remember) SendBit: ld de, $FFFF ; This is for the timing loop rr c ; This rotates the register c right and puts the right ;bit in the carry flag. So each loop has it's bit ;put in the carry flag. Pretty neat. JUMP_NC(SendR) ; If there is no carry (i.e. the current bit is 0) ;then send a R ld a, $E8 ; Else send a W because we have a 1 JUMP_(SendIt) ; Then actually Send it!! SendR: ld a, $D4 ; We have a 0, so send a R (D4h) SendIt: out ($07), a ; This actually sends it! WaitConfirmation: in a, ($07) ; Read the port and $03 ; Mask off bits 1 and 0 (see above text) JUMP_Z(Continue2); If it is zero (both R and W pulled to ground, ;then continue in a, ($07) ; If not, then read the port and try again and $03 JUMP_Z(Continue2) dec de ; Both wern't active that means the calc on the ;other side hasn't received it (The other TI should ;pull the other one to ground to show that it has ;recieved the bit) so loop through and try again. ;It uses de as a counter (it was set in the beg) ld a, d or e ; This basiclly does or e,d and will make z 0 if both ;d and e are zero, or de is zero. (i.e. counter is ;0 and we are done with loop, or a time-out) JUMP_NZ(WaitConfirmation) Error2: pop af ret Continue2: ;jp ErrorHandler; Branislav suggested this was an error handler, ;I don't know, but whatever the case don't include it ;in your implementations. Instead, put in a jr to your ;own error handlers. ld a, $C0 ; Get ready to clear R & W (C0h = both off, see above) out ($07), a ; Actually clear them ld de, $FFFF ; Get de counter ready for next loop to make sure ;link is cleared. when de reaches 0 it times out. Clearloop: dec de ld a, d or e ; Again this is or e,d and will continue if de is not 0 JUMP_Z(Error2) ; We timed out, so go to error handler (see above) in a, ($07) ; Read the port 7 again and $03 ; Performs a Self-Destruct cp $03 ; makes sure link is cleared, or both are not active ;or both are at 5V JUMP_NZ(Clearloop); If not, then clear and wait again. djnz SendBit ; Basiclky a 'dec b' & 'jr nz, SendBit' It will loop ;again to send the next bit pop af ret ; Goes back to your program ;/------------------------------------------------------------------------\ ;|This routine clears the bottom nine lines, for use with the menu display| ;|No nothing for this routine | ;\------------------------------------------------------------------------/ clearbottom: ld hl,$FF70 ld bc,$008F ld (hl),0 push hl pop de inc de ldir ret savebottom: ld hl,$FF70 ld bc,$0090 ld de,$8641 ldir ret restorebottom: ld hl,$8641 ld bc,$0090 ld de,$FF70 ldir ret ;*************************************************** ;This routine checks strings of length in b to see if they are equal ;Input: b -length of both strings ; hl-pointer to first string ; de-pointer to second string ;Note: a zero($00) in the string will be equal to anything, because this ; fits my purpose ;Output: zflag set or reset ;Destroys: a hl is left at end of string, de destroyed ;*************************************************** checkstring: push bc ld a,(de) cp (hl) jr z,byteequal ld a,(hl) or a jr z,checknumber checkstring2: pop bc checkstringend: ;this accounts for if it stops early inc hl ;to get hl at end djnz checkstringend ld a,1 cp 0 ret checknumber: ld a,(de) sub $30 res 7,a dec a dec a and %11111000 ;mask to see if anything above bit 3 is set cp 0 jr z, byteequal bit 7,a jr nz,byteequal ;if set, means two decs put number jr checkstring2 byteequal: inc hl inc de pop bc djnz checkstring ld a,0 cp 0 ret ;********************* Display Menu routine ************************* ;Description: Draws the menu bar at the bottom of the screen ;Parameters: none ;Destroys: a, b, hl displaymenu: ld hl, VIDEO_MEM+$380 ld b, 32 displaymenuloop1: ld (hl), $FF inc hl djnz displaymenuloop1 ld b, 36 ld a, $C0 displaymenuloop2: ld (hl), a inc hl inc hl inc hl rra cp 3 jr nz, displaymenuloop2 ld a, $C0 dec hl dec hl djnz displaymenuloop2 ld a, $FE ld (VIDEO_MEM+$38F), a ld (VIDEO_MEM+$39F), a ret erasebell: ld hl,(PROGRAM_ADDR) ld de,bellpic2 add hl,de ld de,$FFCF ex de,hl ld b,4 erasebell2: push bc ld bc,$0010 ld a,(de) and (hl) ld (hl),a add hl,bc inc de pop bc djnz erasebell2 ret getkeys: push bc push hl ld b, 7 ld a, %01111111 getkeyloop: rlca out (1),a nop nop nop nop push af in a, (1) cpl or a jr nz,gotkey pop af djnz getkeyloop xor a keyend: ld hl,stored_key ld b,(hl) ld (hl),a cp b jr nz,keyend2 ld a,$00 keyend2: ld b,$40 keyend3: nop nop djnz keyend3 pop hl ;if something, in b goes to a pop bc ret gotkey: pop hl ;chud off stack, can I get rid of the use of this hl push af ld a,%00000111 xor b ;7 -> 0, 6->1, 2 -> 5 rlca ;don't need shift cause no chance of hitting top bit rlca rlca pop bc gotkeyloop: rr b inc a jr c,keyend jr gotkeyloop prefwords: .db "Preferences",0 .db " VT100 (ANSI)",0 .db " Local Echo",0 .db " Outbound CR/LF",0 .db " Inbound CR/LF",0 .db " Split Screen",0 .db " Set Function Keys",0 savedprefs: .db 1,1,1,0,0 funckeywords: .db "Function Keys",0 funckeywords2: .db "Press Fkey to change",0 funckeywords3: .db "to:",0 tabtable: .db %00000000,%00000000,%00000000,%00000000,%00000000 .db %00000000,%00000000,%00000000,%00000000,%00000000 chartable: .db 13,33,33,0 .db 37,34,34,0 .db 61,35,35,0 .db 86,36,36,0 .db 112,37,37,0 .db 0,0 chartable2: .db 12,38,38,0 .db 38,39,39,0 .db 62,59,59,0 .db 87,60,60,0 .db 113,62,62,0 .db 0,0 chartable3: .db 12,63,63,0 .db 36,64,64,0 .db 62,92,92,0 .db 87,95,95,0 .db 113,96,96,0 .db 0,0 chartable4: .db 12,123,123,0 .db 38,124,124,0 .db 62,125,125,0 .db 87,126,126,0 .db 108,$09,"TAB",0 crlftable: .db $0D,$0A bellpic: .db %00000001 .db %00000011 .db %00000111 .db %00001111 bellpic2: .db %11111110 .db %11111100 .db %11111000 .db %11110000 statusgood: .db $1B,"[0n" statusbad: .db $1B,"[3n" whatareyou: .db $1B,'[','?','1',59,'0','C' cursorresponse: .db $1B,'[',$00,$00,';',$00,$00,'R' ;the extra spaces are there to account for ;two digit ascii(uggh..) values. That's probably ;not what it will really look like. lflftable: .db $0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A .db $0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A screenwords: .db "v0.9 - (05/06/97)",0 .db "By: ",$0A,"lan ",$0B,"ailey",0 .db "",0 .db "Room for: ",0 .db " lines | ",0 diagnosis0: ;x=(totallines) .db " : ( GET MORE MEM",0 ;0 < x < 10 diagnosis1: ; .db " : [ NO VT100",0 ;9 < x < 32 diagnosis2: ; .db " : ) GREAT!",0 ;31 < x < 128 diagnosis3: ; .db " ;-) SUPER!!",0 ;127 < x < 240 diagnosis4: ; .db " :^o WOW!!!",0 ;239 < x < infinity (not really, but...) menuwords: .db "TERM",0 .db "KEYS",0 .db "HELP",0 .db "QUIT",0 keyhelpwords: .db "[2nd & ALPHA] - Change mode",0 .db "[Arrows] - Scroll screen",0 .db "[F1-F5] - Predefined strings",0 .db "[MORE] - More characters",0 .db "[CUSTOM] - Terminal prefer" .db "ences",0 .db "[GRAPH] - Refresh screen",0 .db "[CLEAR] - Clear buffer",0 .db "[STAT] - This help screen",0 .db "[EXIT] - Exit",0 helpaddress: .db "Go to this address for help:",0 .db "www.mw.sisna.com/users/",0 .db "bailala/zterm/",0 .db $00 .db "Or email me:",0 .db "bailala@mw.sisna.com",0 vt100helpmessage: .db "Email Alan this:",0 functionkeys: .db 20,"ATDT1234567",$20,$20,$20,$20,$20,$20,$20,$20,$20,$0B .db 20,"ATDT9876543",$20,$20,$20,$20,$20,$20,$20,$20,$20,$0B .db 20,"ATDT-------",$20,$20,$20,$20,$20,$20,$20,$20,$20,$0B .db 20,"/join #calc-ti",$20,$20,$20,$20,$20,$20,$0E .db 20,"/nick BobDole",$20,$20,$20,$20,$20,$20,$20,$0D ;format \/\/\/ - - first byte - length of command ; next few from first byte - command ; next two - place to jump execution ; last in table - $FF, terminator vt100table: .db $04,'[',$00,$00,'D' .dw vt100cursorleftlots .db $03,'[',$00,'D' .dw vt100cursorleft ;must add to (PROGRAM_ADDR) .db $03,'[',$00,'C' ;for all \/ \/ \/ .dw vt100cursorright .db $04,'[',$00,$00,'C' .dw vt100cursorrightlots .db $03,'[',$00,'A' .dw vt100cursorup .db $04,'[',$00,$00,'A' .dw vt100cursoruplots .db $03,'[',$00,'B' .dw vt100cursordown .db $04,'[',$00,$00,'B' .dw vt100cursordownlots .db $05,'[',$00,';',$00,'H' .dw vt100changecursor .db $06,'[',$00,$00,';',$00,'H' .dw vt100changeud .db $06,'[',$00,';',$00,$00,'H' .dw vt100changelr .db $07,'[',$00,$00,';',$00,$00,'H' .dw vt100changeudlr .db $05,'[',$00,';',$00,'f' .dw vt100changecursor .db $06,'[',$00,$00,';',$00,'f' .dw vt100changeud .db $06,'[',$00,';',$00,$00,'f' .dw vt100changelr .db $07,'[',$00,$00,';',$00,$00,'f' .dw vt100changeudlr .db $03,'[','2','J' .dw vt100entirescreen .db $03,'[','1','J' .dw vt100erasebegcursor .db $02,'[','J' .dw vt100erasecursorend .db $03,'[','0','J' .dw vt100erasecursorend .db $05,'[',$00,';',$00,'r' .dw vt100setscrolling .db $06,'[',$00,';',$00,$00,'r' .dw vt100setscrollingb .db $06,'[',$00,$00,';',$00,'r' .dw vt100setscrollingt .db $07,'[',$00,$00,';',$00,$00,'r' .dw vt100setscrollingtb .db $01,'7' .dw vt100storecoords .db $01,'8' .dw vt100restorecoords .db $01,'D' .dw vt100index .db $01,'M' .dw vt100reverseindex .db $01,'E' .dw vt100nextline .db $03,'[','2','K' .dw vt100eraseline .db $02,'[','K' .dw vt100eraseendline .db $03,'[','0','K' .dw vt100eraseendline .db $03,'[','1','K' .dw vt100erasecursor .db $02,'[','m' .dw vt100cursorstyle .db $03,'[',$00,'m' .dw vt100cursorstyle .db $05,'[',$00,';',$00,'m' .dw vt100cursorstyle .db $07,'[',$00,';',$00,';',$00,'m' .dw vt100cursorstyle .db $09,'[',$00,';',$00,';',$00,';',$00,'m' .dw vt100cursorstyle .db $01,'H' .dw vt100settab .db $02,'[','g' .dw vt100cleartab .db $03,'[','0','g' .dw vt100cleartab .db $03,'[','3','g' .dw vt100clearalltabs .db $03,'[','5','n' .dw vt100statusrep .db $02,'[','c' .dw vt100whatareyou .db $03,'[','0','c' .dw vt100whatareyou .db $01,'c' .dw vt100reset .db $03,'[','6','n' .dw vt100cursorreport .db $02,'#',$00 ;this accounts for vt100 commands impossible on 85 .dw vt100timefinish ;this label just jumps them back to the end of vt100 .db $03,'[',$00,'q' .dw vt100timefinish .db $05,'[',$00,';',$00,'q' .dw vt100timefinish .db $07,'[',$00,';',$00,';',$00,'q' .dw vt100timefinish .db $09,'[',$00,';',$00,';',$00,';',$00,'q' .dw vt100timefinish .db $02,'(','A' .dw vt100timefinish .db $02,')','A' .dw vt100timefinish .db $02,'(','B' .dw vt100timefinish .db $02,')','B' .dw vt100timefinish .db $02,'(',$00 .dw vt100timefinish .db $02,')',$00 .dw vt100timefinish .db $01,'O' .dw vt100timefinish .db $01,'N' .dw vt100timefinish .db $05,'[','2',';',$00,'y' .dw vt100timefinish .db $03,'[',$00,'h' .dw vt100timefinish .db $03,'[',$00,'l' .dw vt100timefinish .db $04,'[',$00,$00,'h' .dw vt100timefinish .db $04,'[',$00,$00,'l' .dw vt100timefinish .db $04,'[','?',$00,'h' .dw vt100timefinish .db $04,'[','?',$00,'l' .dw vt100timefinish .db $05,'[','?',$00,$00,'h' .dw vt100timefinish .db $05,'[','?',$00,$00,'l' .dw vt100timefinish .db $01,'=' .dw vt100timefinish .db $01,'>' .dw vt100timefinish .db $FF introut: ex af,af' exx ld a,(cursorcount) inc a ld (cursorcount),a cp $40 CALL_Z(putcursor) ld a,(bellcounter) dec a ld (bellcounter),a cp 0 CALL_Z(erasebell) exx ex af,af' jp $38 introutend: ztermpicture: .db $70,$00,$00,$00,$00,$00,$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$FF,$FE,$00,$00,$00,$00,$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$FF,$FC,$00,$00,$00,$00,$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$70,$38,$80,$40,$00,$00,$00,$00,$00,$00 .db $00,$00,$00,$00,$00,$00,$00,$70,$FF,$DF,$F9,$FE,$1F,$1F,$00,$00 .db $00,$00,$00,$00,$00,$00,$00,$E0,$FF,$CF,$F0,$FF,$0F,$BE,$00,$00 .db $00,$00,$00,$00,$00,$00,$01,$C0,$8C,$4C,$00,$C3,$0D,$F6,$00,$00 .db $00,$00,$00,$00,$00,$00,$03,$80,$0C,$0F,$C0,$FE,$0C,$E6,$00,$00 .db $00,$00,$00,$00,$00,$00,$07,$00,$0C,$0F,$E0,$F8,$0C,$46,$00,$00 .db $00,$00,$00,$00,$00,$00,$0E,$07,$0C,$0F,$C0,$DC,$0C,$06,$00,$00 .db $00,$00,$00,$00,$00,$00,$1F,$FF,$8C,$0C,$00,$CE,$0C,$46,$00,$00 .db $00,$00,$00,$00,$00,$00,$3F,$FF,$9E,$0F,$F0,$C7,$0C,$A6,$00,$00 .db $00,$00,$00,$00,$00,$00,$7F,$FF,$BF,$1F,$F9,$E3,$9E,$4F,$00,$00 .db $00,$00,$00,$00,$00,$00,$00,$07 ;6+7 .end ;drgad