Title Input a Line (18_Sept_84) ; ; Copyright 1984 ; Morrow Designs, Inc ; San Leandro, Ca ; .z80 aseg org 0100h ; ;---------------------------------------------------------------------- ; Equates (18_Sept_84) ;--------------------- ; Cr equ 0Dh ;Carriage Return Del equ 7Fh ;Delete Bell equ 07h ;Console Bell Code Cursor_Right equ 0Ch ;(^L) Move Cursor 1 Position Right Cursor_Left equ 08h ;(^H) Move Cursor 1 Position Left Max_Line_Length equ 64 ;Maximum Length of a Line (will be 240) ;System_ConIn equ 0FE09h ;System_ConOut equ 0FE0Ch page 60 ;---------------------------------------------------------------------- ; Main Line of the Line Editor (19_Sept_84) ;------------------------------------------ ; Input_Line: ld hl,Edit_Line ;HL:= Pointer to Edit Line ld (hl),0 ;Reset the Current Cursor Position call Print_Line IlLp1: call System_ConIn ;Loop Get a Character ld hl,Edit_Commands ; HL:= Pointer to Edit Commands call Command_Lookup ; Lookup Char in Command Table ld de,Edit_Line ; DE:= Pointer to Line call Indirect_HL ; Execute it jr IlLp1 ; Execute Indirectly Through the HL Pair ;--------------------------------------- ; Indirect_HL: jp (hl) page ;---------------------------------------------------------------------- ; Print the Current Line (18_Sept_84) ;------------------------------------ ; 1) This routine prints a line from the Current Cursor Position to the ; end of the line. The line format is the same as a Bdos console ; input routine, that is, one byte that's the maximum line length, ; followed by one byte that's the current line length followed by ; the line. ; 2) The Unused part of the line is printed as blanks ; 3) Register Usage: ; BC -> Used to hold the Max and Crnt line lengths ; HL -> Enter Pointing to the Start of the Line Structure ; Print_Line: push hl ld e,(hl) ;E:= Current Cursor Position inc hl ld c,(hl) ;C:= Maximum Line Length inc hl ld b,(hl) ;B:= Current Line Length inc hl ld a,b ;A:= Current Character Count cp e ;If (Current Cursor NOT at End of Line) jr z,PlSk1 ld d,0 ; DE:= Cursor Offset add hl,de ; HL:= Pointer to Crnt Line Pos. sub e ld b,a ; B:= Character Counter PlLp1: push hl ; Repeat push bc ld c,(hl) ; C:= Current Character call System_ConOut ; Print the Character pop bc pop hl inc hl ; Increment Line Pointer djnz PlLp1 ; Until (Line Length - 1 eq 0) PlSk1: pop hl push hl inc hl ld a,(hl) ;A:= Maximum Line Length inc hl ;(HL:= Pointer to Current Line Length) sub (hl) ;If (We're Not at the end of the line) jr z,PlSk2 ld b,a ; B:= Count PlLp2: ld c,' ' ; Repeat C:= Space push bc call System_ConOut ; Print a Space pop bc djnz PlLp2 ; Until (Count - 1 eq 0) PlSk2: pop hl ld b,(hl) ;A:= Current Cursor Position inc hl ;(HL:= Pointer to Max Line Length) ld a,(hl) sub b ;If (Current Cursor at End of Line) ret z ; Return ld b,a ;B:= BackSpace Count PlLp3: ld c,Cursor_Left ;Repeat push bc call System_ConOut ; BackSpace pop bc djnz PlLp3 ;Until (Count - 1 eq 0) ret ;Return page ;---------------------------------------------------------------------- ; Lookup a Command (19_Sept_84) ;------------------------------ ; 1) Register Usage: ; Entry ; A -> Potential Command ; HL -> Pointer to the Base of the Command Table ; Exit ; HL -> Pointer to command if found, undefined otherwise ; Command_Lookup: ld b,(hl) ;B:= Length of the Command Table inc hl ;HL:= Start of Command Table ClLp1: cp (hl) ;Loop If (Potential Command eq Table) jr z,ClSk1 ; Break inc hl inc hl inc hl ; HL:= Start of Next Entry djnz ClLp1 ; If (Counter - 1 eq 0) ld hl,Cmd_Insert ; HL:= Insert Command ret ; Return ClSk1: inc hl ;HL:= Start of Command Vector push de ld e,(hl) inc hl ld d,(hl) ex de,hl ;HL:= Vector to Command pop de ret ;Return page ;---------------------------------------------------------------------- ; Move the Cursor One Position to the Right (18_Sept_84) ;------------------------------------------------------- ; Cmd_Mov_Right: ex de,hl ld a,(hl) ;A:= Current Cursor Position inc hl inc hl cp (hl) ;If (Current Cursor eq End of Line) ret z ; Return dec hl dec hl ;Else inc (hl) ; Increment Current Cursor ld c,Cursor_Right ; C:= Cursor 1 Pos Right call System_ConOut ; Move the Cursor ret ; Return ;---------------------------------------------------------------------- ; Move the Cursor One Position to the Left (18_Sept_84) ;------------------------------------------------------ ; Cmd_Mov_Left: ex de,hl ld a,(hl) ;A:= Current Cursor Position or a ;If (Current Cursor eq Begin Line) ret z ; Return dec (hl) ;Else Decrement Current Cursor ld c,Cursor_Left ; C:= Cursor 1 Pos Left call System_ConOut ; Move the Cursor ret ; Return page ;---------------------------------------------------------------------- ; Delete the Current Character (18_Sept_84) ;------------------------------------------ ; Cmd_Del_Crnt: ret ;---------------------------------------------------------------------- ; Delete One Character to the Left of the Cursor (18_Sept_84) ;------------------------------------------------------------ ; Cmd_Del_Left: ex de,hl ;HL:= Start of the Line Buffer ld a,(hl) ;A:= Current Cursor Offset or a ;If (Current Position eq Start of Line) ret z ; Return dec (hl) ;Decrement the Current Cursor Offset ld e,a ld d,0 ;DE:= Current Cursor Offset inc hl inc hl ld a,(hl) ;A:= Current Line Length dec (hl) ;Decrement the Current Line Length inc hl sub ret ; Check for current cursor at zero ; Check for line length of zero ; ; Set Length of Move:= Current Line Length - Current Cursor Offset ; Set Start of Move:= Base of Line Data + Current Cursor Offset ; Set Destination of Move:= Start of Move - 1 ; Move the Line ; ; adjust current cursor ; adjust line length ;---------------------------------------------------------------------- ; Return to the Calling Routine (18_Sept_84) ;------------------------------------------- ; Cmd_Return: jp 0 ;---------------------------------------------------------------------- ; Insert a Character into the Current Line (19_Sept_84) ;------------------------------------------------------ ; 1) Register Usage: ; A -> Enter equal to the Character to Insert ; DE -> Enter pointing to the start of the Line buffer ; Cmd_Insert: ex de,hl ;HL:= Start of the Line push hl push af ld e,(hl) ;E:= Current Cursor Position inc hl ld a,(hl) ;C:= Maximum Line Length inc hl cp (hl) ;If (Current Line Length eq Maximum) jr nz,IcSk1 call Terminal_Beep ; Beep the Terminal Bell pop af pop de ret ; Return IcSk1: ld a,(hl) inc (hl) ;Increment the Current Line Length sub e ld c,a ld b,0 ;BC:= Length (Crnt Leng - Crnt Cursor) ld d,0 ;(DE:= Current Cursor Position Offset) inc hl ;(HL:= Pointer to Start of Line) add hl,de ;HL:= Source (Crnt Cursor + Line Base) push hl pop de inc de ;DE:= Destination (Source + 1) push hl call Move_a_Block ;Make room for the Character pop hl pop af ld (hl),a ;Install the New Character pop hl push hl call Print_Line ;Print the Line pop hl inc (hl) ;Increment the Current Cursor Offset ld c,Cursor_Right call System_ConOut ;Move the Cursor 1 Position Right ret ;Return page ;---------------------------------------------------------------------- ; Sound the Console Bell (18_Sept_84) ;------------------------------------ ; Terminal_Beep: ld c,Bell ;C:= Bell Code call System_ConOut ;Ring the Terminal Bell ret ;---------------------------------------------------------------------- ; Move_a_Block (1_Mar_84) ;------------------------ ; 1) This routine moves a block of memory. The block can overlay itself. ; 2) Register Usage: ; BC -> Byte Count ; DE -> Destination ; HL -> Source ; Move_a_Block: ld a,b ;If (Length of move is zero) or c ret z ; Return push hl or a ;(clear the carry) sbc hl,de ;If (Source eq Destination) pop hl ret z ; Return jr c,MBSk1 ;Else If (Source gt Destination) ldir ; Move the Block Up ret ; Return MBSk1: push hl ex de,hl ;Else (Source lt Destination) or a ; (clear the carry) add hl,bc ; Dest:= Dest + Byte_Count dec hl ; (move pointer back to last char) ex de,hl pop hl add hl,bc ; Source:= Source + Byte_Count dec hl ; (move pointer back to last char) lddr ; Move the Block Down ret ; Return page ;---------------------------------------------------------------------- ; Data Area (18_Sept_84) ;----------------------- ; Edit_Line: db 0 ;Current Cursor Position db Max_Line_Length ;Maximum Line Length db Etl - Btl ;Current Line Length Btl: db 'This is a Test Line' Etl: ds Max_Line_Length - (Etl - Btl) ,' ' ;---------------------------------------------------------------------- ; Editing Command Table (18_Sept_84) ;----------------------------------- ; Edit_Commands: db (Edit_End-Edit_Start)/3 ;Number of Edit Commands Edit_Start: db 6 ;^F Move Cursor Right one position dw Cmd_Mov_Right db 1 ;^A Move Cursor Left one position dw Cmd_Mov_Left db 7 ;^G Delete Char Under Cursor dw Cmd_Del_Crnt db Del ;Del Delete char In Front of Cursor dw Cmd_Del_Left db Cr ;Ret Enter the Line dw Cmd_Return Edit_End: page ;---------------------------------------------------------------------- ; Execute the System's Console Input Routine (18_Sept_84) ;-------------------------------------------------------- ; System_ConIn: ld hl,0FE09h ld a,14 call 0FE00h ret ;---------------------------------------------------------------------- ; Execute the System's Console Output Routine (18_Sept_84) ;--------------------------------------------------------- ; System_ConOut: ld hl,0FE0Ch ld a,14 call 0FE00h ret end