Title Terminal Initialization Program for the MD11 (4_Jun_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; John Zalabak ; .z80 Aseg org 0100h ;---------------------------------------------------------------------- ; Equates (25_May_84) ;-------------------- ; Rev equ 20h ;Bios/Bdos Equates Bios_Entry equ 0 ;Bios Entry Point Bdos_Entry equ 5 ;Bdos: Entry Vector Location Bdos_ConIn equ 1 ; Console Input Bdos_ConOut equ 2 ; Console Output Bdos_PString equ 9 ; Print a Sting on the Console Bdos_ConBuf_in equ 10 ; Read Console input buffer Bdos_Open_File equ 15 ; Open a File Bdos_Close_File equ 16 ; Close a File Bdos_Read_Seq equ 20 ; Read Sequential Bdos_Write_Seq equ 21 ; Write Sequential Bdos_Set_DMA equ 26 ; Set the DMA Address ;Non Printing Ascii Equates Control_C equ 03h ;Control C (Force CPM Warm Boot) Tab equ 09h ;Tab Lf equ 0Ah ;Line Feed Cr equ 0Dh ;Carriage Return End_of_File equ 1Ah ;End of File Character ClrScr equ 1Ah ;Clear Screen Esc equ 1Bh ;Escape Space equ 20h ;Space ;Error Codes and Returned Status Open_Dat_Error equ 0FFh ;Can't open the Terminal.Dat File Open_Sys_Error equ 0FEh ;Can't open the Cpm3.Sys file Disk_Read_Error equ 0FDh ;Error occured in a disk read operation Unexpected_End equ 0FCh ;Unexpected End (Eol or Eof) Bad_Definition equ 0FBh ;Illegal Character Dict_Overflow equ 0FAh ;Dictionary Buffer has overflowed No_Titles equ 0F9h ;No terminal titles to build menu Not_in_Dict equ 0F8h ;Current Element is not in dictionary No_Delimiter equ 0F7h ;Equal sign is missing in definition Bad_Type_Byte equ 0F6h ;Unknown Line Type Definition Bad_Level equ 0F5h ;Terminal Level Definition Out of Range Bad_Symbol equ 0F4h ;Bad Symbol in Definition ;Length defintions Record_Length equ 80h ;Length of one record Max_Dict_Length equ 10h ;Maximum Length of dictionary buffer Max_Rec_Length equ 80h ; " " " a Record Max_Stack_Space equ 20h ; " " " the main stack ;Block Definitions $Type_Cursor equ 10000000b ;Cursor Definition String $Type_Ascii equ 01000000b ;Ascii Cursor Position Format Flag $Type_Row equ 00100000b ;Row Definition $Type_Col equ 00010000b ;Column Definition $Type_Level equ 00001000b ;Level Defintion $Type_Char equ 00000100b ;Non Printing Character Definition $Type_Escape equ 00000010b ;Escape Table Definition $Type_Controì eqõ 00000001â ;Controì Tablå Definition ;Other Definitions Default_Dma equ 80h ;Start of the default dma buffer Status_EOF equ 1 ;End of file status Null equ 0FFh ;Null Key Definition page ;====================================================================== ; Main Line of Terminal Initialization (18_Apr_84) ;================================================= ; Init_Main: call Read_Dat_File ;Read the Terminal.Dat File or a ;If (there was an error) jr nz,ImErr ; Return (Error) call Get_Titles ;Build a table of title string pointers or a ;If (there were no titles found) jr nz,ImErr ; Return (Error) ImLp1: call Print_Menu ;Repeat Print the Menu call Get_Response ; Get the user's response or a jr nz,ImLp1 call Verify_Response ; Verify the response or a jr nz,ImLp1 ;Until (The response is valid) call Translate_Def ;Translate the Definition or a ;If (there was an error) jr nz,ImErr ; Return (Error) call Read_Sys_File ;Read the Cpm3.Sys File or a ;If (there was an error) jr nz,ImErr ; Return (Error) call Install_Def ;Install the Definitions jp Bios_Entry ;Return (Normal) ;Fatal Error Return ImErr: call Report_Errors ;Report the Error jp Bios_Entry ;Return (Error) page ;---------------------------------------------------------------------- ; Read the Terminal.Dat File (9_Apr_84) ;-------------------------------------- ; Read_Dat_File: ld de,FCB_Dat ;DE:= Pointer to Terminal.Dat FCB ld c,Bdos_Open_File ;C:= Open File Function call Bdos_Entry ;Open the File ld de,Memory_Image ;DE:= Starting Address of program cp 4 ;If (file was NOT successfully opened) jr c,BCLp1 ld a,Open_Dat_Error ; Can't open Terminal.Dat ret ; Return ;Read Until the End of the File BCLp1: push de ;Loop DE:= Current Load Address ld c,Bdos_Set_DMA ; C:= Set DMA Function call Bdos_Entry ; Set the current DMA address ld de,FCB_Dat ; DE:= Address of FCB ld c,Bdos_Read_Seq ; C:= Read Sequential Function call Bdos_Entry ; Read the next record pop de ld hl,Record_Length add hl,de ex de,hl ; DE:= Pointer to start next record or a jr z,BCLp1 ;Until (End of File or Error Encounterd) cp Status_Eof ;If (the end of the file encountered) ld a,0 ret z ; Return No Error ld a,Disk_Read_Error ret ;Return Disk Read Error page ;---------------------------------------------------------------------- ; Build a List of Terminal Title Lines (11_May_84) ;------------------------------------------------- ; 1) This routine builds a list of Terimal Title line addresses into ; the one dimensional array Title_Buffer. ; 2) Register Usage: ; D -> Flag for comments and definition lines ; E -> Adjusted Line length counter (minus leading white space) ; HL -> Memory Image Pointer ; Get_Titles: ld hl,Title_Buffer ld (Title_Pointer),hl ;Title_Buffer_Pointer:= Start buffer ld hl,Memory_Image ;Memory_Image_Pointer:= Start buffer GtLp1: ld de,0 ;Repeat Flag and line length:= 1 call Strip_White ; Remove the leading white space cp Cr ; If (1st Char is a Cr) jr nz,GtSk1 inc hl jr GtLp1 ; Goto Start of Loop GtSk1: cp ';' ; If (1st Char is Comment) jr z,GtLp2 cp '*' jr nz,GtLp3 GtLp2: call Get_Next_Line ; Remove the Line jr GtLp1 ; Goto Start of Loop GtLp3: cp End_of_File ; Repeat jr nz,GtSk2 ; If (End of File eq True) ld (Temp_Buffer),hl ex de,hl ; DE:= Pointer to Eob ld hl,(Title_Pointer) ld (hl),e inc hl ld (hl),d ; Save Start addr last line inc hl ld a,(Max_Titles) ; If (Titles were found) or a ld a,0 ; (Status=Ok) ret nz ; Return ld a,No_Titles ; Else (Status=Not_Ok) ret ; Return GtSk2: cp '=' ; Else If (char eq def) jr nz,GtSk3 ld d,a ; Set Non_Title Flag GtSk3: inc hl ; Inc Memory Image Pointer inc e ; Inc Line Length ld a,(hl) ; Get the next character cp Cr jr nz,GtLp3 ; Until (End of Line) ld a,d ; If (line eq definition) or a jr nz,GtSk4 ld a,(Max_Titles) inc a ld (Max_Titles),a ; Increment Title Count push hl ;(Save current pointer) or a sbc hl,de ex de,hl ;DE:= Start of last line ld hl,(Title_Pointer) ld (hl),e inc hl ld (hl),d ;Save Start addr last line inc hl ld (Title_Pointer),hl ;Update Title Pointer pop hl ;(Restore current pointer) GtSk4: jr GtLp1 page ;====================================================================== ; Print the Menu (20_Apr_84) ;=========================== ; 1) This routine prints the menu in two columns. If the number of ; entries is odd then the left hand column will be the longest. ; 2) Register Usage: ; B -> Title Count ; DE -> String Pointer ; HL -> Pointer to Current Title ; Print_Menu: ld de,Menu_Heading ld c,Bdos_Pstring call Bdos_Entry ;Print the Menu Heading call Setup_Columns ;Set column starting titles and numbers ld a,(Max_Titles) ld b,a ;B:= Number of titles to print ;Print the Left Column Title PmLp1: ld a,(Left_Number) ;Loop ld c,a ; C:= Left Column Number inc a ld (Left_Number),a ld hl,(Left_Col) ; HL:= Pointer to Title Pointer ld e,(hl) inc hl ld d,(hl) inc hl ld (Left_Col),hl ; Update Left Column Title Pointer ex de,hl ; HL:= Pointer to start title String push bc call Print_Title ; Print the Title pop bc dec b ; If (All Titles Printed) ret z ; Return ;Print the Right Column Number ld a,(Right_Number) ld c,a ; C:= Right Column Number inc a ld (Right_Number),a ld hl,(Right_Col) ; HL:= Pointer to Title Pointer ld e,(hl) inc hl ld d,(hl) inc hl ld (Right_Col),hl ; Update Right Col Pointer ex de,hl ; HL:= Pointer to start title String push bc call Print_Title ; Print the Title ld c,Bdos_ConOut ; C:= Console Output Function ld e,Cr ; E:= Carriage Return call Bdos_Entry ; Print the Character ld c,Bdos_ConOut ; C:= Console Output Function ld e,Lf ; E:= Carriage Return call Bdos_Entry ; Print the Character pop bc dec b ; If (All Titles Printed) ret z ; Return jr PmLp1 ;---------------------------------------------------------------------- ; Setup the Columns for printing the menu (30_Apr_84) ;---------------------------------------------------- ; 1) This routine sets up both the column numbers and the title ; pointers for printing the menu. The menu format consists of ; two columns, each entry is preceeded by a choice number. ; 2) Register Usage: ; DE -> Used in address calcualtion ; HL -> General Purpose Pointer ; Setup_Columns: ld a,0 ld (Left_Number),a ;Left_Column_Number:= 1 ld de,Title_Buffer ld (Left_Col),de ;Left_Column_Pointer:= Start Title Buffer ld hl,(Title_Pointer) ;HL:= End of Title Buffer or a sbc hl,de ;HL:= Length of Title Buffer srl l ;HL:= 1/2 way through Title Buffer ld a,l srl a jr nc,ScSk1 ;If (the number of entries is odd) inc a ; Make Right Column Number Shorter inc hl ; Make Right Column Pointer Shorter ScSk1: add hl,de ld (Right_Col),hl ;Right_Column_Pointer:= Start Right Col ld (Right_Number),a ;Right_Column_Number:= 1/4 buffer leng ret page ;---------------------------------------------------------------------- ; Print the Title (30_Apr_84) ;---------------------------- ; 1) Register Usage ; C -> Current Choice Number ; HL -> Pointer to the current Title ; Print_Title: push hl push bc ;(save the input parameters) ld b,6 ;B:= Number of Leading Spaces PtLp1: push bc ;Repeat ld c,Bdos_ConOut ; C:= Bdos Console Ouput Function ld e,Space ; E:= Space call Bdos_Entry ; Print a Space pop bc djnz PtLp1 ;Until (all leading spaces printed) pop bc ld a,'A' add a,c ;Add Ascii Offset to Column Offset ld e,a ld c,Bdos_ConOut call Bdos_Entry ;Print the Column Letter ld c,Bdos_ConOut ld e,')' call Bdos_Entry ;Print a ')' ld c,Bdos_ConOut ld e,Space call Bdos_Entry ;Print a Space pop hl ld b,25 ;Column Count:= 25 PtLp2: ld a,(hl) ;While ( (Char ne Carriage Return) and cp Cr jr z,PtSk1 cp Lf ; and (Char ne Line Feed) ) jr z,PtSk1 push bc inc hl ; Increment the Title Pointer push hl ld c,Bdos_ConOut ; C:= Console Output Function ld e,a ; E:= Next character of Title call Bdos_Entry ; Print the Character pop hl pop bc djnz PtLp2 ; Decrement the column count PtSk1: ld a,b PtLp3: or a ;While (Column Count ne 0) ret z push af ld c,Bdos_ConOut ; C:= Console Output ld e,Space ; E:= Space call Bdos_Entry ; Print a Space pop af dec a ; Decrement the column count jr PtLp3 ;====================================================================== ; Get the Response from the user (11_May_84) ;=========================================== ; 1) This routine gets the response from the user. If the response is ; valid then the accm is returned equal to zero (else its returned ; non-zero). ; 2) The HL register pair is returned pointing to the base of the title ; line. ; 3) Register Usage: ; DE -> Offset to the start of the title line ; HL -> Returned Pointing to the start of the title line. ; Get_Response: ld de,Response_Msg ld c,Bdos_PString call Bdos_Entry ;Print the prompt string GrLp1: ld c,Bdos_ConIn call Bdos_Entry ;Get the User's Response and 5Fh ;(force response to upper case) cp Control_C ;If (Response eq Force Warm Boot) jp z,Bios_Entry ; Goto Warm Boot sub 'A' ;Adjust the Response ld e,a cp 0 ;If ( (Response lt 0) or ret c ld a,(Max_Titles) dec a cp e ; (Response gt Max_Titles) ) ret c ; Return sla e ld d,0 ;DE:= Offset to title line ld hl,Title_Buffer add hl,de ;HL:= Pointer to title ld e,(hl) inc hl ld d,(hl) inc hl ld (Start_Def),de ;Save the Start of the Definition ld e,(hl) inc hl ld d,(hl) ld (End_Def),de ;Save the End of the Defintion ld a,0 ;Returned_Status:= Title Found ret ;Return ;====================================================================== ; Verify the User's Response (11_May_84) ;======================================= ; 1) This routine verifies the user's response by presenting the ; the title of the chosen terminal and then demanding a Y/N ; validation from the user. ; Verify_Response: ld de,VRmsg1 ld c,Bdos_PString call Bdos_Entry ;Print 'Is ' ld hl,(Start_Def) ;HL:= Pointer to start of the title ld b,25 ;B:= Max Title Length ld c,Bdos_ConOut ;C:= Console Output Function VrLp1: ld a,(hl) ;While ( (Char ne Carriage Return) and cp Cr jr z,VrSk1 cp Lf ; and (Char ne Line Feed) ) jr z,VrSk1 inc hl ; Increment the Title Pointer push bc push hl ld e,a ; E:= Next character of Title call Bdos_Entry ; Print the Character pop hl pop bc djnz VrLp1 ; Decrement the column count VrSk1: ld de,VrMsg2 ld c,Bdos_PString call Bdos_Entry ; Print ' the correct choice?' VrLp2: ld c,Bdos_ConIn ;Loop call Bdos_Entry ; Get the User's Response and 5Fh ; (force response to upper case) cp Control_C ; If (Response eq Force Warm Boot) jp z,Bios_Entry cp 'Y' ; If (Response is Yes) jr nz,VrSk2 ld a,0 ret ; Return (Ok) VrSk2: cp 'N' ; Else If (Response is No) jr nz,VrLp2 ld a,0FFh ret ; Return (Not Ok) page ;====================================================================== ; Translate the Definitions (25_May_84) ;====================================== ; 1) This routine is the main line of the definition parser. First the ; title line is removed. Then successive lines are read and decoded ; until either an end of file mark or the start of the next ; definition is encountered. ; 2) Comments within the definition are ignored. ; 3) A count is kept of the number of lines within the definition. This ; is used in error reporting. ; Translate_Def: ld hl,(Start_Def) ;HL:= Pointer to start title line call Get_Next_Line ;Remove the current Line cp End_of_File ;If (End of file read) jr nz,TdLp1 ld a,0 ret ; Return TdLp0: inc hl ;(move the text pointer past current char) TdLp1: ld a,(Line_Count) ;Loop inc a ld (Line_Count),a ; Increment the def line number call Strip_White ; Strip white space cp Cr ; If (Char eq Cr) jr z,TdLp0 ; Goto 1st Loop cp ';' ; If (Char eq Comment) jr z,TdSk0 cp '*' jr nz,TdSk1 TdSk0: call Get_Next_Line ; Remove the Line jr TdLp0 TdSk1: cp End_of_File ; If (Char eq End of File) ld a,UnExpected_End ; (Error: UnExpected Eof) ret z ; Return push hl ; If (End of definition) ld de,(End_Def) xor a ; (Status:= Ok) sbc hl,de pop hl ret nc ; Return TdSk2:: call Fill_Dict_Buf ; (move line def into Dict_Buf) call Strip_White ; Move to the Equal Sign cp '=' ld a,No_Delimiter ; If (equal sign missing) ret nz ; Return (error) push hl ld hl,Main_Dictionary call Dict_Lookup ; Lookup the Code ex de,hl pop hl or a ; If (Code in Main Dict) jr nz,TdSk3 call Proc_String ; Process the String or a ; If (Error) ret nz jr TdLp1 TdSk3: push hl ; Else ld hl,Aux_Dictionary ; Lookup Aux Dict call Dict_Lookup ex de,hl pop hl or a ; If (Code not found) ret nz ; Return (error) call Set_DE_to_Def ; DE:= Pointer to Data ld a,(de) ; A:= Line Type cp $Type_Cursor ; If (Line_Type is Cursor) jr nz,Tdsk4 call Proc_Cursor ; Process cursor definition or a ; If (error true) ret nz ; Return jr TdLp1 TdSk4: cp $Type_Level ; Else If (Line_Type is Level) jr nz,TdSk5 call Proc_Level ; Process Level Definition or a ; If (Error true) ret nz ; Return jr TdLp1 TdSk5: ld a,Bad_Type_Byte ; Else Type is invalid ret ; Return page ;---------------------------------------------------------------------- ; Process a Cursor Definition (4_Jun_84) ;--------------------------------------- ; Proc_Cursor: inc hl PClp1: call Strip_White ;Repeat call Fill_Dict_Buf ; Move Token Into Dict_Buffer or a ; If (End of Line) jr nz,PCsk1 inc hl ; HL:= Moved past Eol Character ret ; Return PCsk1: push hl ld hl,Aux_Dictionary ; Lookup String in Aux Dict call Dict_Lookup ex de,hl pop hl or a ; If (String is in the dict) jr nz,PCsk2 call Set_DE_to_Def ; DE:= Pointer to Data ld a,(de) ; A:= Line Type and $Type_Row or $Type_Col ; If (Symbol is Row or Col) jr z,PClp1 inc hl PCsk2: ld a,(Dict_Length) ld b,a ; B:= Length of Dict Buffer ld de,Dict_Buffer ; DE:= Pointer to Dict Buffer ;&&& PClp2: ld a,(de) ; Repeat cp '^' ; If (Char eq Control Char) jr nz,PCsk3 inc de dec b jr z,PCsk3 ; If (another char) ld a,(de) ; Get Character sub 40h ; Convert to cntrl PSsk3: call Store_Temp_Buf ; Store the Character inc de ; Inc dict_buffer pointer djnz PCLp2 ; Until (dict_buffer emptied) jr PCLp1 ;---------------------------------------------------------------------- ; Process a Level Definition (4_Jun_84) ;-------------------------------------- ; 1) This routine reads, translates and verifies a LEVEL definition. ; Proc_Level: inc hl call Strip_White ;A:= Ascii Terminal Level cp '0' ;If (Terminal Level within limits) jr c,PLbad cp '4' jr nc,PLbad and 0Fh ; A:= Absolute Terminal Level ld (Terminal_Level),a ; Update the terminal level call Get_Next_Line ; Strip the remainder of the line inc hl ; HL:= Moved past Eol Character ld a,0 ret ; Return PLbad: ld a,Bad_Level ;Else Returned_Status:= Bad Terminal Level ret ; Return page ;---------------------------------------------------------------------- ; Process a String Definition (4_Jun_84) ;--------------------------------------- ; 1) This routine does the processing for a teminal translation string. ; The type (e.g. Clear screen) has already been looked up before this ; routine is entered. First a check is made for the equal sign. Then ; a pointer to the start of the translation string is saved in the ; the block definition. Finally the body of the definition (if ; there is one) is translated and terminated by a byte of 0FFh. ; 2) Register Usage: ; A -> General Purpose ; DE -> On entry is a Pointer to a pointer to the string def. ; HL -> Pointer to into the Terminal.dat source file. ; Proc_String: inc hl ;(move past the equal sign) call Set_DE_to_Def ;DE:= Pointer to Data (line title) push hl ;(save the text pointer) ex de,hl inc hl inc hl ;(move HL to start of pointer in block def) ld de,(Temp_Buffer) ld (hl),e inc hl ld (hl),d ;Setup the pointer in the block def. pop hl ;(restore text pointer) PSLp1: call Strip_White ;While (There are more characters) call Fill_Dict_Buf ; Fill Dict_Buffer with next token or a jr z,PSdone push hl ld hl,Aux_Dictionary ; Lookup String in Aux Dict call Dict_Lookup ex de,hl pop hl or a ; If (String is in the dict) jr nz,PSsk1 call Set_DE_to_Def ; DE:= Pointer to Data ld a,(de) ; A:= Line Type cp $Type_Char ; If (Symbol isn't Char) ld a,Bad_Symbol ret nz ; Return (error) inc de ; Else ld a,(de) ; Get the Char call Store_Temp_Buf ; Store it jr PSLp1 PSsk1: ld a,(Dict_Length) ld b,a ; B:= Length of Dict Buffer ld de,Dict_Buffer ; DE:= Pointer to Dict Buffer PSlp2: ld a,(de) ; Repeat cp '^' ; If (Char eq Control Char) jr nz,PSsk2 inc de dec b jr z,PSsk2 ; If (another char) ld a,(de) ; Get Character sub 40h ; Convert to cntrl PSsk2: call Store_Temp_Buf ; Store the Character inc de ; Inc dict_buffer pointer djnz PSLp2 ; Until (dict_buffer emptied) jr PSLp1 PSdone: ld a,0FFh ;A:= Terminator call Store_Temp_Buf ;Terminate the string inc hl ;HL:= Moved past End of Line Character ld a,0 ret ;Return page ;---------------------------------------------------------------------- ; Set DE register pair to Start of Block Definition (25_May_84) ;-------------------------------------------------------------- ; 1) On entry, the DE pair is pointing to the argument field of a ; dictionary entry. The Argument field of a dictionary entry points ; to an arbitrary length block definition. This routine moves the ; DE pair so that it points to the start of the data in the block ; defintion. ; 2) Register Usage: ; DE -> Enter Pointing to Pointer in Dictionary ; Exit Pointing to Block Definition ; HL -> Preserved ; Set_DE_to_Def: push hl ;(save the Text pointer) ex de,hl ld e,(hl) inc hl ld d,(hl) ;DE:= Pointer to Type pop hl ;(restore text pointer) ret ;Return ;---------------------------------------------------------------------- ; Store a String Definition in the Temp Buffer (4_Jun_84) ;-------------------------------------------------------- ; 1) This routine stores one byte in the Temp_Buffer located at the ; end of the Terminal.dat file (its setup in Get_Titles). ; Store_Temp_Buf: push hl ld hl,(Temp_Buffer) ;HL:= Pointer into temp_buffer ld (hl),a ;Save the character inc hl ld (Temp_Buffer),hl ;(increment the pointer) pop hl ret ;Return page ;---------------------------------------------------------------------- ; Get the Next Line (21_May_84) ;------------------------------ ; 1) This routine reads characters until a new-line or and end-of-file ; is read. ; 2) Register Usage: ; A -> Current character ; HL -> Pointer into the source file. ; Get_Next_Line: ld a,(hl) ;While ((Char ne Cr) and (Char ne EOF)) cp Cr ret z cp End_of_File ret z inc hl jr Get_Next_Line ; Loop ;---------------------------------------------------------------------- ; Strip Leading White Space (11_May_84) ;-------------------------------------- ; 1) This routine removes leading white-space (comma, tab and line-feed) ; 2) Register Usage ; A -> Holds the last character read on return ; HL -> Pointer into the source file. (returned pointing at the ; current character). ; Strip_White: ld a,(hl) ;While (Char ne Space, Tab or Lf) cp Space jr z,SwSkp1 cp Tab jr z,SwSkp1 cp Lf jr z,SwSkp1 ret SwSkp1: inc hl jr Strip_White ; Loop page ;---------------------------------------------------------------------- ; Fill the Dictinary buffer (4_Jun_84) ;------------------------------------- ; 1) This routine fills the Dictionary Buffer with characters until ; the first white-space character, Number, carriage return or End ; of File mark. ; 2) Register Usage: ; A -> Returned equal to the number of characters in buffer ; C -> Counter for Dict_Buffer Length ; DE -> Pointer into the dictionary buffer ; HL -> Pointer to the current position in the source file ; Fill_Dict_Buf: ld de,Dict_Buffer ;DE:= Start of Dict buf ld c,0 ;C:= Counter GwLp1: ld a,(hl) ;While (Char ne White Space) cp Space jr z,GwDone cp Tab jr z,GwDone cp Lf jr z,GwDone cp 30h ; If (Char eq Number) jr c,GwSk1 cp 3Ah jr c,GwDone ; Break GwSk1: cp Cr ; If (Char eq end_of Line/File) jr z,GwDone cp End_of_File jr z,GwDone ; Break inc hl ; Buf_Pointer:= Buf_Pointer + 1 ld (de),a ; Dict_Buffer:= Current Character inc de ; Dict_Pointer:= Dict_Pointer + 1 inc c ; Counter:= Counter + 1 jr GwLp1 GwDone: ld a,c ld (Dict_Length),a ;Save the Length ret ;Return page ;---------------------------------------------------------------------- ; Dictinonary Lookup (1_Mar_84) ;------------------------------ ; 1) This routine searches the dictionary for String matching ; the one in the dictionary buffer. ; 2) Register Usage: ; A -> Returned = 0 for NO Error ; B -> Counter for the length of the string ; DE -> Pointer into the Dictionary Buffer ; HL -> Enter pointing to Start of Dictionary to search ; Dict_Lookup: ld a,(Dict_Length) ld c,a ;C:= current dictionary buffer length or a ;If (there's no name to look for) jr nz,SrcLp1 ld a,Not_in_Dict ; Set Returned Error Status ret ; Return SrcLp1: ld (Save_Pointer),hl ;Loop Save the pointer to the arg inc hl inc hl ; HL:= pointer to length byte ld a,(hl) ; A:= Length of Name or a ; If (its the End of the Dict.) jr nz,SrcSk2 ld a,Not_in_Dict ; Set Return Error Status ret ; Return SrcSk2: ld b,a ; B:= Length of Dictionary String inc hl ; HL:= Pointer to Start of String cp c ; If (the Length Matches) jr nz,SrcNxt ld de,Dict_Buffer ; DE:= Start of Dict buf SrcLp2: ld a,(de) ; Repeat and 5Fh ; (force upper case) cp (hl) ; If (no match) jr nz,SrcNxt ; Break inc hl ; inc dict pointer inc de ; inc Temp pointer djnz SrcLp2 ; Until (Count eq 0) ld hl,(Save_Pointer) ; HL:= Pointer to arg. ld a,0 ; Flag:= Success ret ; Return SrcNxt: ld e,b ld d,0 ; DE:= Offset add hl,de ; HL:= Pointer to start next name jr SrcLp1 page ;---------------------------------------------------------------------- ; Read the Cpm3.Sys File (10_Apr_84) ;----------------------------------- ; Read_Sys_File: ret ld de,FCB_Sys ;DE:= Pointer to Cpm3.Sys FCB ld c,Bdos_Open_File ;C:= Open File Function call Bdos_Entry ;Open the File ld de,Memory_Image ;DE:= Starting Address of program cp 4 ;If (file was NOT successfully opened) jr c,RSFLp1 ld a,Open_Dat_Error ; Can't open Terminal.Dat ret ; Return ;Read Until the End of the File RSFLp1: push de ;Loop DE:= Current Load Address ld c,Bdos_Set_DMA ; C:= Set DMA Function call Bdos_Entry ; Set the current DMA address ld de,FCB_Sys ; DE:= Address of FCB ld c,Bdos_Read_Seq ; C:= Read Sequential Function call Bdos_Entry ; Read the next record pop de ld hl,Record_Length add hl,de ex de,hl ; DE:= Pointer to start next record or a jr z,RSFLp1 ;Until (End of File or Error Encounterd) cp Status_Eof ;If (the end of the file encountered) ld a,0 ret z ; Return No Error ld a,Disk_Read_Error ret ;Return Disk Read Error page ;---------------------------------------------------------------------- ; Install the Definitions (10_Apr_84) ;------------------------------------ ; Install_Def: ret ;====================================================================== ; Report Errors (4_Jun_84) ;========================= ; 1) Report Errors on the console. ; 2) Register Usage: ; A -> Has Error Code on entry ; B -> Counter ; C -> Holds copy of Error Code ; Report_Errors: push af ld de,CrLf ;DE:= Pointer to Cr/Lf String ld c,Bdos_PString ;C:= Print String Function call Bdos_Entry ;Print Carriage Return Line Feed ld a,(Line_Count) ;If (line number is NOT Zero) or a jr z,ReSk1 ld de,ErrOpn ld c,Bdos_PString call Bdos_Entry ; Print the Opening Message ld a,(Line_Count) ld l,a ld h,0 ; HL:= Line Number call Print_Number ; Print the line numbeint the Opening Message ReSk1: pop af ld c,a ;C:= Error Code to Find ld b,Max_Error ld hl,Error_Table ;HL:= Start of the error table ReLp1: ld a,(hl) ;Repeat A:= Table's Error Code inc hl ld e,(hl) inc hl ld d,(hl) ; DE:= Pointer to String inc hl ; (HL equal to start next entry) cp c ; If (Code eq table) jr z,REprn ; Goto Print djnz RELp1 ;Until (the whole tables been checked) ld de,NoCode ;(set pointer to 'Unrecognized Error') REprn: ld c,Bdos_PString ; call Bdos_Entry ; Print the Message ret page ;---------------------------------------------------------------------- ; Print Line Number (12_Apr_84) ;------------------------------ ; 1) This routine prints the 16 bit number (passed in the HL) in ascii. ; 2) Register Usage: ; HL -> 16 bit number to be printed ; Print_Number: ld a,l ;If (The Number is Zero) or h jr nz,Dsk1 ld b,3 ; Set Leading space count to max DLp1: push bc ; Repeat ld c,Bdos_ConOut ; Set the function number ld e,Space call Bdos_Entry ; Print a Space pop bc djnz DLp1 ; Until (Leading space count eq 0) ld c,Bdos_ConOut ld e,'0' call Bdos_Entry ; Print the zero ret ; Return Dsk1: ld bc,0FFFFh push bc ;Put end flag on stack DLp2: ld bc,10 ;Repeat divisor:= 10 (base 10) call divide ; Divide push hl ; Save the remainder ld hl,9 or a sbc hl,de ex de,hl ; (Move quotient to dividend) jp c,DLp2 ;Until (quotient is less than 9) DLp3: ld a,l ;While (Result eq 0) or a jr nz,DLp4 ld e,Space ld c,Bdos_ConOut call Bdos_Entry ; Print a Space pop hl ; Get the next number jr DLp3 DLp4: add a,'0' ;Repeat ld e,a ; Convert number to ascii ld c,Bdos_ConOut call Bdos_Entry ; Print the number pop hl ; Get the next number ld a,l cp 0FFh jr nz,DLp4 ;Until (end of stack flag has been read) ld e,Space ld c,Bdos_ConOut call Bdos_Entry ;Print a Space ret ;Return ;---------------------------------------------------------------------- ; 16 bit Divide ;-------------- ; divide 16-bit number in [hl] by [bc] ; on exit, [de] is 16-bit quotient, [hl] is remainder ; divide: add hl,hl ;hi *2 ex de,hl ;[de] becomes lo ld hl,0 ;init hi ld a,16 ;16 bits divid0: adc hl,hl ;Repeat hi *2 or a ; clear borrow sbc hl,bc ; sbc hl,bc ;hi=hi-divisor ccf ; invert borrow for shift later jr c,divid1 ; if borrow { adc hl,bc ; Restore the value of the HL ccf divid1: ex de,hl ; get lo adc hl,hl ; lo *2 + remainder ex de,hl dec a ; count-- jr nz,divid0 ;Until (bit count eq 0) ret page ;====================================================================== ; Dictionary Macro Definitions (1_Mar_84) ;======================================== ; ; Generate a Dictionary Entry (1_Mar_84) ;--------------------------------------- ; 1) This macro generates an entry in the function key dictionary. ; 2) Each entry in the dictionary has the following form ; 1 byte Type of Entry ; 2 bytes Pointer to definition string ; n bytes Name of function key ; DfDict macro Name, pntr local L1, L2 dw pntr ;Pointer to the default output string db l2 - l1 ;length of Name string l1: db '&Name' ;Name of function key l2: endm ; Terminate the Key Dictionary (28_Feb_84) ;----------------------------------------- ; DfEnd macro ds 4,0 ;4 bytes of zero to end the table endm page ;---------------------------------------------------------------------- ; Key Dictionary (21_May_84) ;--------------------------- ; 1) This Dictionary contains all of the Title Codes ; Main_Dictionary: DfDict HOME, Def_Home ; Level 1 Definitions DfDict CLR, Def_Clear DfDict LEFT, Def_Left DfDict RIGHT, Def_Right DfDict UP, Def_Up DfDict DOWN, Def_Down DfDict HI, Def_Hi ; Level 2 Definitions DfDict LO, Def_Lo DfDict CEOL, Def_CEol DfDict CEOS, Def_CEos DfDict INSLINE, Def_InsLine ; Level 3 Definitions DfDict INSCHAR, Def_InsChar DfDict DELCHAR, Def_DelChar DfDict DELLINE, Def_DelLine DfEnd ;---------------------------------------------------------------------- ; Level 1 Definitions ;-------------------- ; Def_Clear: db $Type_Control or $Type_Escape db 1Ah dw 0 Def_Home: db $Type_Control db 1Eh dw 0 Def_Left: db $Type_Control db 8 dw 0 Def_Right: db $Type_Control db 0Ch dw 0 Def_Up: db $Type_Control db 0Bh dw 0 Def_Down: db $Type_Control db 0Ah dw 0 ; Level 2 Definitions ;-------------------- ; Def_Hi: db $Type_Escape db '(' dw 0 Def_Lo: db $Type_Escape db ')' dw 0 Def_CEol: db $Type_Escape db 'T' dw 0 Def_CEos: db $Type_Escape db 'Y' dw 0 ; Level 3 Definitions ;-------------------- ; Def_InsChar: db $Type_Escape db 'Q' dw 0 Def_InsLine: db $Type_Escape db 'W' dw 0 Def_DelChar: db $Type_Escape db 'E' dw 0 Def_DelLine: db $Type_Escape db 'R' dw 0 page ;---------------------------------------------------------------------- ; Aux Dictionary (4_Jun_84) ;-------------------------- ; 1) This dictionary contains everything but the title codes. ; Aux_Dictionary: DfDict CURSOR, Def_Cursor DfDict ASCII, Def_Ascii DfDict R+, Def_Row DfDict C+, Def_Column DfDict ESC, Def_Escape DfDict SP, Def_Space DfDict LEVEL, Def_Level DfEnd ;End of the table ;---------------------------------------------------------------------- ; Aux Definitions ;---------------- ; Def_Cursor: db $Type_Cursor ;Type:= Cursor Definition db 0 Def_Ascii: db $Type_Ascii ;Type:= Ascii Cursor Position Format db 0 Def_Row: db $Type_Row ;Type:= Row Offset db 0 Def_Column: db $Type_Col ;Type:= Column offset db 0 Def_Escape: db $Type_Char ;Type:= Non Printing Character db 1Bh ;Escape Character Def_Space: db $Type_Char ;Type:= Non Printing Character db 20h ;Space Def_Levelº dâ $Type_Level ;Type:= Level Definition db 0 page ;---------------------------------------------------------------------- ; Error Code Tables and Message Strings (4_Jun_84) ;------------------------------------------------- ; ; Error Message String Lookup Table ;---------------------------------- ; Error_Table: db Open_Dat_Error ;Cannot open the Termianl.Dat File dw ODEmsg db Open_Sys_Error ;Cannot open the Cpm3.Sys File dw OSEmsg db Disk_Read_Error ;Error occured in a disk read operation dw DREmsg db UnExpected_End ;Unexpected End (Eol or Eof) dw UEmsg db Bad_Definition ;Illegal Character in definition dw BDmsg db Dict_Overflow ;Dictionary Buffer has overflowed dw DOmsg db No_Titles ;No terminal titles to build menu dw NTmsg db Not_in_Dict ;Current Element not in the dictionary dw NDmsg db No_Delimiter ;Equal Sign is missing in definition dw NEmsg db Bad_Type_Byte ;Line Definition Type is UnKnown dw BBmsg db Bad_Level ;Terminal Level Definition Out of Range dw BLmsg db Bad_Symbol ;Bad Symbol in definition dw BSmsg End_Table: Max_Error equ ( (End_Table - Error_Table)/3 ) + 1 page ; Error Message Strings (4_Jun_84) ;--------------------------------- ; ODEmsg: db 'Cannot open the Terminal.Dat file $' OSEmsg: db 'Cannot open the Cpm3.Sys file $' DREmsg: db 'Error occured in a disk read operation $' UEmsg: db 'Unexpected End (Eol or Eof) $' BDmsg: db 'Illegal Character $' DOmsg: db 'Dictionary Buffer has overflowed $' NTmsg: db 'No terminal titles to build menu $' NDmsg: db 'Current Element not in the dictionary $' NEmsg: db 'Missing Delimiter $' BBmsg: db 'Line Definition Type is Unknown $' BLmsg: db 'Terminal Level Definition Out of Range $' BSmsg: db 'Bad Symbol in Definition Line $' NoCode: db 'Unrecognized Error $' ErrOpn: db Cr,Lf, 'Error on line $' page ;---------------------------------------------------------------------- ; Other Text Strings (10_May_84) ;------------------------------- ; Menu_Heading: db Cr,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf db Cr,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf,Lf db 'MD-11 Terminal Initialization Program, Rev ' db ((Rev and 0F0h) shr 4) + '0', '.',(Rev and 0Fh) + '0' db ' Copyright 1984' db Cr,Lf,'Morrow Designs Inc.' db Tab,Tab,Tab,Tab,Tab,Tab,'San Leandro, Ca' db Cr,Lf,Lf,Lf, '$' Response_Msg: db Cr,Lf,Lf db ' Please enter the Letter of Your Choice $' CrLf: db Cr,Lf,'$' VrMsg1: db Cr,Lf,Lf db ' Is $' VrMsg2: db ' the correct choice? (Y/N) $' page ;---------------------------------------------------------------------- ; Local FCB's Area (9_Apr_84) ;---------------------------- ; FCB_Dat: db 0,'TERMINALDAT',0 ;Fcb name field ds 19,0 ;Blank file remainder of FCB FCB_Sys: db 0,'CPM3 SYS',0 ;Fcb name field ds 19,0 ;Blank file remainder of FCB page ;---------------------------------------------------------------------- ; General Parameter Area (21_May_84) ;----------------------------------- ; Save_Pointer: dw 0 ;Save loc for pointer to dict argument Dict_Length: db 0 ;Length of the Dictionary buffer Dict_Buffer: ds 20h ;Dictionary buffer Line_Count: dw 0 ;Current Line Number Start_Def: dw 0 ;Start of the current definition End_Def: dw 0 ;End of the current definition Left_Col: dw 0 ;Pointer to Left hand column Left_Number: db 0 ;Left Column Choice Number Right_Col: dw 0 ;Pointer to Right hand column Right_Number: db 0 ;Right Column Choice Number Max_Titles: db 0 ;Total Number of Titles Title_Pointer: dw 0 ;Pointer into the title buffer Title_Buffer: ds 60h,0 ;Title Buffer Table_Pointer: dw Table_Space ;Pointer into the table space Table_Space: ds 80h ;Space for Escape and Control Tables Terminal_Level: db 0 ;Terminal definition level Esc_Tbl_Length: db 0 ;Escape Table Length Cnt_Tbl_Length: db 0 ;Control Table Length Escape_Vector: dw Table_Space ;Vector to start of the Escape Table Control_Vector: dw Table_Space ;Vector to start of the Control Table Temp_Buffer: dw 0 ;Pointer to end of Memory_Image Memory_Image: db 0 ;Label for start of buffer end