<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>
; ______ _ _ _ __ __ _ ; | ____| | (_) | \ \ / / | | ; | |__ __| |_| |_ ___ _ __ \ \ /\ / /___ _ __ __| |___ ; | __| / _` | | __|/ _ \| '__| \ \/ \/ // _ \| '__/ _` / __| ; | |____| (_| | | |_| (_) | | \ /\ /| (_) | | | (_| \__ \ ; |______|\__,_|_|\__|\___/|_| \/ \/ \___/|_| \__,_|___/ ; block editor keyCC equ -125 ; key code for ctrl c (copy line) keyCV equ -106 ; key code for ctrl v (paste line) keyCI equ -119 ; key code for ctrl i (insert line) keyCD equ -124 ; key code for ctrl d (delete line) keyCO equ -113 ; key code for ctrl o (previous block) keyCP equ -112 ; key code for ctrl p (next block) keyF9 equ 15 ; key code for function 9 (back) keyF7 equ 1 ; key code for function 7 (tab) keyF4 equ 2 ; key code for function 4 (escape) keyF3 equ 7 ; key code for function 3 (erase line) keyF2 equ 4 ; key code for function 2 (insert/overwrite) keyF1 equ 3 ; key code for function 1 (del) keyFE equ 11 ; cursor up keycode keyFS equ 8 ; cursor left keycode keyFD equ 9 ; cursor right keycode keyFX equ 10 ; cursor down keycode keyFeq equ 5 ; keycode for function = (quit) keyRET equ 13 ; keycode for ENTER key savkey equ scrx ; borrow scrX memory location for saving ; keypresses _edit clr @csrflg ; clear shared cursor flash flag ; (shared with forcnt) clr @temp2 ; next block to load mov *stack,r0 ; get address from BLOCK mov r0,r7 ; copy it jne _edit1 ; if not zero then continue inct stack ; else BLOCK failed to load block. b @retB0 ; Remove vdp address from stack and exit ; determine if block is dirty or clean: ; display * next to block number if dirty otherwise display a space _edit1 jgt _edit4 ; jump if dirty bit not set li r6,_edit4 ; load return address bl @disupd ; write CHANGED to screen _edit4 andi r7,>7fff ; remove dirty bit if set mov r7,*stack ; write it back, we'll use it further on... bl @csrdef ; define cursor udg clr @epage ; set page to first page clr @temp ; initialise insert/overwrite mode bl @draws ; draw static parts of the display bl @drawd ; draw dynamic parts of the display bl @insovr ; display mode clr @csrx ; used for cursor x clr @csry ; used for cursor y clr @cursrd ; reset cursor delay bl @delay ; small delay to give the user time to data 30000 ; release the enter key! ; editor main loop ; keyboard scanning and auto-repeat edml2 bl @scnkey ; get key in r7 edml4 mov r7,@savkey ; save the keypress ci r7,>ffff ; nothing pressed? jeq docfl ; if nothing pressed then do cursor flash li r13,edml3 ; set something pressed - set return point ; for post keypress processing jmp chkent ; process the key press edml3 mov @kdel,r0 ; get keyboard repeat delay from kdel srl r0,8 ; upper byte to lower byte sla r0,1 ; move right one. multiplied by 2 edml5 bl @scnkey ; scan again c r7,@savkey ; same key as last time? jeq edml6 ; if yes then decrement delay jmp edml4 ; different key - go process it edml6 dec r0 ; decrement counter jne edml5 ; check again li r13,edml7 ; counter expired. set return point jmp chkent ; go process key edml7 movb @kdel+1,r0 ; get short delay from kdel low-byte srl r0,8 ; to low byte jmp edml5 ; repeat ; do cursorflash docfl li r0,>0100 a r0,@cursrd jne edml2 ; time to flash cursor? loop if not inv @csrflg ; invert the cursor flag jeq oncsr ; if 0 do cursor on bl @csroff ; else do cursor off jmp edml2 oncsr bl @csron jmp edml2 ; check for enter key chkent ci r7,keyRET ; return/enter pressed? jne keycor ; skip if not clr @csrx ; move to left most column clr @epage ; move to left page inc @csry ; move down a line mov @csry,r0 ; check y ci r0,16 ; 16? jne keyen1 ; skip if not clr @csry ; clip to 15 keyen1 bl @drawd ; render display b *r13 ; continue ; check control keys ; ; check CTRL O (previous block) keycor ci r7,keyCO jne keycpr mov @lstblk,@temp2 dec @temp2 ; decrement block number to load rt4th inct stack ; remove BLOCK address from stack li r12,_next ; restore pointer to NEXT b @retB0 ; return to forth ; ; check CTRL P (next block) keycpr ci r7,keyCP jne keycdr mov @lstblk,@temp2 inc @temp2 ; increment block number to load jmp rt4th ; return to forth ; ; check CTRL D (delete line) keycdr ci r7,keyCD ; ctrl d pressed? jne keycir ; skip if not bl @needud ; set this blocks' status to dirty ; calculate end address of buffer mov *stack,r6 ; vdp buffer address ai r6,1023 ; point to last byte of buffer ; calculate start point mov @csry,r0 ; get current line inc r0 ; move down a line sla r0,6 ; multiply by buffer line length a *stack,r0 ; add vdp buffer start address keycd1 li r2,64 ; read a line... mov @here,r1 ; ...into scroll buffer bl @_vmbr ; read the line ai r0,-64 ; move up one line mov @here,r1 ; source li r2,64 ; count bl @_vmbw0 ; write the line ai r0,128 ; move down 2 lines c r0,r6 ; done all? jlt keycd1 ; loop if not ; blank the last line... r6 points to last byte, so... mov r6,r0 ; place in r0 for VDP ai r0,-63 ; move to start of last line in buffer li r1,>2000 ; space character li r2,64 ; line length bl @vsbwmi ; write spaces bl @rsrc ; render source b *r13 ; continue ; ; check CTRL I (insert line) keycir ci r7,keyCI ; ctrl i pressed? jne keyccr ; skip if not bl @needud ; set this blocks' status to dirty ; get current line address mov @csry,r6 ; current y ci r6,15 ; on the last line? jeq keyci2 ; if so, just erase last line sla r6,6 ; multiply by line length a *stack,r6 ; add vdp buffer address ; find last line of buffer mov *stack,r0 ; buffer start address ai r0,14*64 ; move to last line but 1 (15th line) keyci1 mov @here,r1 ; buffer address li r2,64 ; count bl @_vmbr ; read into buffer ai r0,64 ; move down a line mov @here,r1 ; buffer address