Title Terminal Initialization Program for the MD11 (25_Jun_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; John Zalabak ; .z80 Aseg Org 0100h ;---------------------------------------------------------------------- ; Index: ;------- ; Init_Main Main Line of Terminal Initialization ; ; Setup_Dat_File Setup for Reading the Terminal Definition File ; Read_Dat_File Read the Terminal Definition File ; ; Get_Titles Build a List of Terminal Title Lines ; Print_Menu Print the Menu ; Setup_Columns Setup the Columns for printing the menu ; Print_Title Print the Title ; Get_Response Get the Response from the user ; ; Verify_Response Verify the User's Response ; ; Translate_Def Translate the Definitions ; Proc_Cursor Process a Cursor Definition ; Store_Dca Save The Direct Cursor Address Character ; Proc_Row_Col Process Row/Column Cursor Offsets ; Proc_Level Process a Level Definition ; Proc_String Process a String Definition ; Check_Aux Check The Aux Dictionary ; Check_Control Check if the current Character is a control Character ; Check_Number Check for a Literal Numeric Definition ; Fill_Numb_Buf Fill the Number Buffer ; Valid_Number Check for a Valid Ascii/Ascii-Hex Number ; Store_Temp_Buf Store a Byte in the Temp Buffer ; Get_Next_Line Get the Next Line ; Get_Token Get the Next Token ; Strip_White Strip Leading White Space ; White_Space? Check for White Space ; End_Line? Check for End_of_Line or End_of_File ; Dict_Lookup Dictinonary Lookup ; Set_DE_to_Def Set DE register pair to Start of Block Definition ; ; Verify_Level Verify the Terminal Level page 60 ; Build_Tables Build The Console Tranlsation Tables ; Setup_Image Setup the Character Table Image ; Build_Trans Build a Translation Table ; Build_Vector Build a Vector Table ; Get_Type_X Get Next Occurance of Type X in Main Dict Defs ; Move_Def Move a Translation Definition ; Move_Down Move a Translation String Down ; Fix_CLR Fix the CLR Screen Entry in the Escape Table: ; Get_Version Check the CP/M version ; ; Install_Cpm2 Install Definitions in a CP/M 2.2 System ; Read_Cpm2_Bios Read the Cp/m 2.2 Bios ; Write_Cpm2_Bios Write the Cp/m 2.2 Bios ; Setup_IX Setup the IX and Initialize Pertinant Values ; Get_Bios_Pntr Get One of the Bios Pointers ; Cpm2_Bias Figure the Memory Bias for Cpm 2.2 ; Cpm2_Level Install Terminal Level for Cpm 2.2 ; Cpm2_Dca Install Direct Cursor Addressing Structure for Cpm 2.2 ; Cpm2_Translate Install Console Translation Structure for Cpm 2.2 ; Install_Cpm3 Install Definitions in a CP/M 3.0 System ; ; Get_Sys_Param Calculate System Parameters for Reading/Writing CPM3.SYS ; Read_Sys_File Read the Bios Portion of CPM3.SYS ; Write_Sys_File Write the Bios Out to Disk ; Read_Sys_Rec Read One Record from the Cp/m System File ; Write_Sys_Rec Write One Record to the Cp/m System File ; Cpm3_Translate Install Console Translation Structure for Cpm 3.0 ; ; Adj_Pointers Adjust the Character Table Pointers ; Adj_Vectors Adjust the Character Table Vectors ; Adj_Free_Space Adjust the Free Space Pointer ; Find_Header Find a Header in the Free Space Pool ; Get_DE_Indr_HL Load the DE register Pair Indirectly Through the HL ; Apply_Bias_DE Apply the Bias to the DE Pair ; Adjust_Vectors Adjust the Character Table Vectors - General Routine ; ; Yes_or_No Get a Yes/No Response from the User ; Print_Closing Print the Closing Message ; ; Report_Errors Report Errors ; ; Print_Number Print Line Number ; RadN_to_Binary Convert from the Current Radix to Binary ; Multiply 16 bit Multiply ; Divide 16 bit Divide page ;---------------------------------------------------------------------- ; Equates (25_Jun_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_Ret_Ver equ 12 ; Return CP/M version 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 Esc equ 1Bh ;Escape ;Length defintions Record_Length equ 80h ;Length of one record Max_Token_Len equ 10h ;Maximum Length of the Token buffer Dca_Len equ 6 ; " " " a Dca String ;File Control Block Definitions Default_Fcb equ 5Ch ;Start of 1st FCB generated by CCP Default_Extent equ Default_Fcb+9 ;Offset to start of FCB's Extent page ;Error Codes and Returned Status Dat_Open_Error equ 0FFh ;Can't open the Terminal.Dat File Dat_Read_Err equ 0FEh ;Error occured in a disk read operation Token_Overflow equ 0FDh ;Token Buffer has overflowed No_Titles equ 0FCh ;No terminal titles to build menu Not_in_Dict equ 0FBh ;Current Element is not in dictionary No_Delimiter equ 0FAh ;Equal sign is missing in definition Bad_Type_Byte equ 0F9h ;Unknown Line Type Definition Bad_Level equ 0F8h ;Terminal Level Definition Out of Range Bad_Symbol equ 0F7h ;Bad Symbol in Definition Invalid_Number equ 0F6h ;Invalid Char in Literal Numeric String Number_Overflo equ 0F5h ;Literal Numeric String is too Long Dca_OverFlo equ 0F4h ;Direct Cursor Address String too Long Insufficient_FS equ 0F3h ;Not Enough Room for Translation Table Sys_Open_Err equ 0F2h ;Unable to Open System file on Disk Sys_Read_Erò eqõ 0F1è ;Unablå tï Reaä Systeí froí thå Disk Sys_Write_Err equ 0F0h ;Unable to Write System to the Disk ;Block Definitions (Masks) $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 ;Block Definitions (Bits) @Type_Cursor equ 7 ;Cursor Definition String @Type_Ascii equ 6 ;Ascii Cursor Position Format Flag @Type_Row equ 5 ;Row Definition @Type_Col equ 4 ;Column Definition @Type_Level equ 3 ;Level Defintion @Type_Char equ 2 ;Non Printing Character Definition @Type_Escape equ 1 ;Escape Table Definition @Type_Controì eqõ 0 ;Controì Tablå Definition page ; Cp/m 3.0 Character Table Offsets Loff3 equ 8 ;Terminal Level Offset Pool3_Offset equ 14h ;Start Free Space Pool (same as Xltab) EtblPtr3_Offset equ 16h ;Escape Lookup Table DcaPtr3_Offset equ 1Eh ;Pointer to Direct Cursor Addr Struct ; Cp/m 2.2 Bios Jump Table Offsets Bios_Offset equ 200h ;Offset: Bios Start from Start Disk Buffer Bios_Address equ 1 ;Address of Bios (Warm Boot Vector Addr) WBoot_Offset equ 4 ;Warm Boot address (Gives base of Bios) RdBlk_Offset equ 37h ;Read a Block from the Floppy Disk WrBlk_Offset equ 3Ah ;Write a Block to the Floppy Disk RamDatX_Offset equ 40h ;RamDatX Area RamDatY_Offset equ 42h ;RamDatY Area Pool2_Offset equ 46h ;Start Free Space Pool (same as Xltab) EtblPtr2_Offset equ 48h ;Escape Lookup Table DcaPtr2_Offset equ 50h ;Start of the Direct Cursor Addr Struct ; RamDatX Area Definitions HstDsk equ 0 ;Host Level Disk HstTrk equ 1 ; " " Track HstSec equ 2 ; " " Sector SecCnt equ 3 ;Sector Count (1 to n) Retry equ 4 ;Error Retry Count HstBuf equ 5 ;Host Buffer ErFlag equ 7 ;Error Flag ;Other Definitions Clear_Code equ 1Ah ;Escape Table Code for Clear Screen Max_Level equ '5' ;Maximum Terminal Level + 1 Disk_Buffer equ 2000h ;Start of Disk Buffer (must be above Rom) Default_DMA equ 80h ;Start of the Default Dma Buffer Status_EOF equ 1 ;End of file status Null equ 0FFh ;Null Key Definition (Terminates Dict) @Column_Flag equ 0 ;Row/Column Flag (see Order:) @Ascii_Flag equ 1 ;Binary/Ascii Flag (see Order:) Token_Number equ 1 ;Token Read was a Number Token_Literal equ 2 ; " " " " Literal page ;====================================================================== ; Main Line of Terminal Initialization (26_Jun_84) ;================================================= ; Init_Main: call Setup_Dat_File ;Setup the FCB for reading the Dat File call Read_Dat_File ;Read the Terminal Definition 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 ;Loop Print the Menu call Get_Response ; Get the user's response or a ; If (Response was Valid) jr nz,ImLp1 call Verify_Response ; Verify the response or a ; If (Repsonse was Yes) jr nz,ImLp1 ; call Translate_Def ; Translate Def or a ; If (Error True) jr nz,ImErr ; Return (Error) call Verify_Level ; If (Level is Ok) or a jr nz,ImLp1 ; Break call Build_Tables ;Build the Console Translation Table call Get_Version ;If (This is a Cp/m 2.2 system) jr z,ImSk1 call Install_Cpm2 ; Install Definitions for Cp/m 2 or a ; If (There was NO Error) jr z,ImOk ; Goto Normal Return jr ImErr ; Else Goto Error Return ImSk1: call Install_Cpm3 ;Else Install Definitions for Cp/m 3 or a ; If (There was NO Error) jr z,ImOk ; Goto Normal Return ImErr: call Report_Errors ;Report the Error jp Bios_Entry ;Return ImOk: call Print_Closing ;Print the Closing Message jp Bios_Entry ;Return page ;---------------------------------------------------------------------- ; Setup for Reading the Terminal Definition File (26_Jun_84) ;----------------------------------------------------------- ; 1) This routine Sets up the Closing Message Flag and the FCB for ; reading the Terminal Definitions File. ; 2) If the First Non_White character of the input line is an astrisk (*) ; then the Closing Message Flag is Set. This suppresses the part ; of the closing message that tells the User to Press Reset. ; 3) The default filename is Terminal.Dat; However, if a filename is ; entered on the input line then it is used instead. The default ; extent for an input line filename is DAT. ; 4) Register Usage: ; A -> General Purpose ; BC -> Counter ; DE -> Destination Pointer ; HL -> Source Pointer ; Setup_Dat_File: ld a,(Default_DMA) ;If (a Command Tail is NOT Present) or a ret z ; Return ld b,a ;B:= Counter ld hl,Default_DMA+1 ;HL:= Start of the Default Dma Buffer SFlp1: ld a,(hl) ;Repeat call White_Space? ; If (Char ne White_Space) jr nz,SFsk1 ; Break inc hl ; Inc Char Pointer djnz SFlp1 ;Until (Counter - 1 eq 0) SFsk1: cp '*' ;If (Char eq Suppress Reset Message) jr nz,SFsk2 ld (Close_Msg_Flag),a ; Set the Suppression Flag ret ; Return SFsk2: ld a,0 ld (Close_Msg_Flag),a ;Reset the Suppression Flag ld a,(Default_Fcb+1) ;If (default FCB has NOT been Setup) cp ' ' ret z ; Return ld bc,8 ;Length:= 8 (file_name_field) ld a,(Default_Extent) ;If (Extent is filled in) cp ' ' jr z,SFsk3 ld bc,11 ; Length:= 11 (whole name) SFsk3: ld de,FCB_Dat+1 ld hl,Default_Fcb+1 ldir ;Move the Default Fcb ret ;Return page ;---------------------------------------------------------------------- ; Read the Terminal Definition File (26_Jun_84) ;---------------------------------------------- ; 1) This routine reads the Terminal Defintions file into memory ; starting at Memory_Image. ; Read_Dat_File: ld de,FCB_Dat ;DE:= Pointer to Terminal Def 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,RDLp1 ld a,Dat_Open_Error ; Can't open Terminal Def File ret ; Return RDLp1: 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,RDLp1 ;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,Dat_Read_Err 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 ;Loop Flag and line length:= 1 call Strip_White ; Remove the leading white space cp Cr ; If ( (1st Char is a Cr) Or jr z,GtSk1 cp ';' ; (1st Char is Comment) ) jr z,GtSk1 cp '*' jr nz,GtLp2 GtSk1: call Get_Next_Line ; Remove the Line jr GtLp1 ; Goto Start of Loop GtLp2: 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,GtLp2 ; 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,' ' ; 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,' ' 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,' ' ; E:= Space call Bdos_Entry ; Print a Space pop af dec a ; Decrement the column count jr PtLp3 page ;====================================================================== ; 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 page ;====================================================================== ; Verify the User's Response (18_Jun_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?' call Yes_or_No ; Get the Response ret ; (Flag set in Yes_or_No) page ;====================================================================== ; Translate the Definitions (22_Jun_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) Comment lines 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 ld a,0 ;If (End of File Read) ret c ; Return 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) Or jr z,TdSk0 cp ';' ; (Char eq Comment) ) jr z,TdSk0 cp '*' jr nz,TdSk1 TdSk0: call Get_Next_Line ; Remove the Line jr TdLp1 TdSk1: push hl ; If (End of definition) ld de,(End_Def) xor a ; (Carry-Cleared/Status:= Ok) sbc hl,de pop hl jr c,TdSk2 ld (Line_Count),a ; Reset the Line Count ret ; Return TdSk2: call Get_Token ; (move line def into Token_Buf) ret c ; If (Error or Eof) Return calì Strip_Whitå » Movå tï thå Equaì 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 ; Return 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 bit @Type_Cursor,a ; If (Line_Type is Cursor) jr z,Tdsk4 call Proc_Cursor ; Process cursor definition or a ; If (error true) ret nz ; Return jr TdLp1 TdSk4: bit @Type_Level,a ; Else If (Line_Type is Level) jr z,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 (14_Jun_84) ;---------------------------------------- ; Proc_Cursor: inc hl ;Move past the equal sign PClp1: call Get_Token ;Repeat Move Token Into Token_Buffer ret c ; If (Error) Exit or a ; If (End of Line) jr nz,PCsk1 inc hl ; HL:= Moved past Eol Character ret ; Return PCsk1: call Check_Aux ; Lookup String in Aux Dict or a ; If (String is in the dict) jr nz,PCsk5 call Set_DE_to_Def ; DE:= Pointer to Data ld a,(de) ; A:= Line Type bit @Type_Row,a ; If (Symbol eq Row) jr z,PCsk2 call Proc_Row_Col ; If (Error) ret c ; Return jr PClp1 PCsk2: bit @Type_Col,a ; If (Symbol eq Column) jr z,PCsk3 call Proc_Row_Col ; If (Error) ret c ; Return jr PClp1 PCsk3: bit @Type_Ascii,a ; If (Symbol is Ascii) jr z,PCsk4 ld a,(Order) set @Ascii_Flag,a ; Set Ascii Flag ld (Order),a jr PClp1 PCsk4: inc de ; Else ld a,(de) ; A:= Symbol Val call Store_Dca ; Store Symbol ret c ; If (Error) Exit jr PCLp1 PCsk5: ld a,(Token_Type) ; Else If (Token Type eq Number) cp Token_Number jr nz,PCsk6 push hl call RadN_to_Binary ; Convert to Binary ld a,l ; A:= Number pop hl call Store_Dca ; Save the Number ret c ; If (Error) then Exit jr PCLp1 PCsk6: ld de,Token_Buffer ; DE:= Pointer to Token Buffer ld a,(Token_Length) ld b,a ; B:= Length of Token Buffer PClp2: call Check_Control ; Else Repeat Process Control Char PCsto: call Store_Dca ; Store in Dca Buffer ret c ; If (Error) Exit inc de ; Inc Token_Buffer pointer djnz PCLp2 ; Until (Token_Buffer emptied) jr PCLp1 page ;---------------------------------------------------------------------- ; Save The Direct Cursor Address Character (14_Jun_84) ;----------------------------------------------------- ; 1) This routine stores one byte in the current dca string after ; checking for Dca OverFlo. ; 2) If there was an Error (Dca Offset too Long) then the carry is ; returned set else its returned cleared. ; 3) Register Usage: ; A -> Character to store ; DE -> Temp Storage and Pointer Calculation ; HL -> Pointer to Save Location ; Store_Dca: push hl push de lä d,á ;Savå thå Characteò iî D ld a,(Dca_Offset) ld e,a inc a ;Increment the Dca Offset cp Dca_Len ;If (Length gt Max) jr c,SDsk1 pop de pop hl ld a,Dca_OverFlo ; A:= Error Code scf ; Flag:= Error ret ; Return SDsk1: ld (Dca_Offset),a ;Update Dca Offset ld a,(Dca_Level) cp 0 ;If (Dca_Level eq 0) jr nz,SDsk2 ld hl,DcaStrt ; HL:= Dca Start String jr SDsk4 SDsk2: cp 1 ;Else If (Dca_Level eq 1) jr nz,SDsk3 ld hl,DcaMid ; HL:= Dca Mid String jr SDsk4 SDsk3: ld hl,DcaEnd ;Else HL:= Dca End String SDsk4: ld a,d ld d,0 add hl,de ;HL:= Pointer to Storage Location ld (hl),a ;Save the Character inc hl ld (hl),0FFh ;ReTerminate the String pop de pop hl or a ;Flag:= No Error (Carry Cleared) ret page ;---------------------------------------------------------------------- ; Process Row/Column Cursor Offsets (21_Jun_84) ;---------------------------------------------- ; 1) This routine processes both Row and Column Offsets and sets the ; Column before Row flag if appropriate. ; 2) If an error Occurs then the carry is returned set else its cleared. ; 3) Register Usage: ; C -> Temporary Storage for Type_* ; DE -> Altered in Subroutine Calls ; HL -> Incremented past Offset Value ; Proc_Row_Col: ld c,a ;C:= Row/Column Flag ld a,(Dca_Level) inc a ld (Dca_Level),a ;Inc Dca Level (Start -> Mid -> End) bit @Type_Col,c ;If ( (Offset eq Column) And jr z,PRsk1 cp 1 ; (Dca_Level eq Mid) ) jr nz,PRsk1 ld a,(Order) set @Column_Flag,a ld (Order),a ; Set Column before Row Flag PRsk1: ld a,0 ld (Dca_Offset),a ;Reset Current Dca Offset to 0 call Fill_Numb_Buf ;Fill the Number Buffer ret c ;If (Error) Then Exit push hl call RadN_to_Binary ;Convert the Number to Binary ld a,(Dca_Level) ld h,a ;(save Dca_Level temporairly in H) ld a,l sub 20h ;Adjust offset Relative to Standard dec h ;If (this is the first offset) pop hl ; (restore HL) jr nz,PRsk3 ld (Offset1),a ; Save Offset1 or a ; Clear Carry ret ; Return PRsk3: ld (Offset2),a ;Else Save Offset2 or a ; Clear Carry ret ; Return page ;---------------------------------------------------------------------- ; Process a Level Definition (25_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 Max_Level ; (equals Max Terminal Level + 1) 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 ld a,0 ret ; Return PLbad: ld a,Bad_Level ;Else Returned_Status:= Bad Terminal Level ret ; Return page ;---------------------------------------------------------------------- ; Process a String Definition (15_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) push hl ;(save the text pointer) call Set_DE_to_Def ;DE:= Pointer to Data (line title) 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 Get_Token ;While (there is another token) ret c ; If (Error) Exit or a jr z,PSdone call Check_Aux ; Lookup String in Aux Dict 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 bit @Type_Char,a ; If (Symbol isn't Char) ld a,Bad_Symbol ret z ; Return (error) inc de ; Else ld a,(de) ; Get the Char call Store_Temp_Buf ; Store it jr PSLp1 PSsk1: ld a,(Token_Type) ; Else If (Token Type eq Number) cp Token_Number jr nz,PSsk2 push hl call RadN_to_Binary ; Convert to Binary ld a,l ; A:= Number pop hl call Store_Temp_Buf ; Save the Number ret c ; If (Error) then Exit jr PSLp1 PSsk2: ld a,(Token_Length) ; Else ld b,a ; B:= Length of Token Buffer ld de,Token_Buffer ; DE:= Pointer to Token Buffer PSlp2: call Check_Control ; Repeat Process Control Chars call Store_Temp_Buf ; Store Character inc de ; Inc Token_Buffer pointer djnz PSLp2 ; Until (Token_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 ;---------------------------------------------------------------------- ; Check The Aux Dictionary (11_Jun_84) ;------------------------------------- ; 1) This routine checks the Aux Dictionary for the String contained ; in the Token Buffer. ; 2) Register Usage: ; DE -> If Found then its returned pointing to the Definition ; HL -> Preserved ; Check_Aux: push hl ld hl,Aux_Dictionary ;Lookup String in Aux Dict call Dict_Lookup ex de,hl ;Move the Defintion Pointer into DE pop hl ret page ;---------------------------------------------------------------------- ; Check if the current Character is a control Character (15_Jun_84) ;------------------------------------------------------------------ ; 1) This routine checks if the current character is a control char. If ; it isn't then the accm is returned UnToutched; Else, the control ; character is converted and returned in the accm. ; 2) Register Usage: ; A -> Returned equal to Char or Converted Control Char ; B -> Token Buffer Length Count ; DE -> Pointer to Current Position in Token Buffer ; Check_Control: ld a,(de) cp '^' ;If (Char ne Control Char) ret nz ; Return djnz CCsk1 ;If (Token_Length - 1 eq 0) inc b ; Restore Token Length ret ; Return CCsk1: inc de ; Increment Token_Buffer_Pointer ld a,(de) ; Get Character sub 40h ; Convert to cntrl ret ;---------------------------------------------------------------------- ; Check for a Literal Numeric Definition (14_Jun_84) ;--------------------------------------------------- ; 1) This routine checks for a literal numeric definition. If the token ; buffer isn't the start of a literal numeric definition (token_buffer ; equal to a Single Quote) then the current character is returned ; with the carry cleared. If this is a numeric defintion then the ; number is moved into the number buffer and the accm is returned ; equal to zero. If there was an error in moving the number into the ; number buffer then the carry is returned set else its returned clear. ; Check_Number: ld a,(de) cp "'" ;If (Char ne Single Quote) jr z,CNsk1 or a ; Clear error Flag ret ; Return (Not a Number) CNsk1: dec b ;If (there are No chars in Token Buf) jr z,CNsk2 inc b ; Restore the Counter or a ; Clear Error Flag ret ; Return (Not a Number) CNsk2: call Fill_Numb_Buf ;Fill the Number Buffer ld a,0 ;Flag:= Its a Number ret ;Return (carry set/cleared in Fill rtn) page ;---------------------------------------------------------------------- ; Fill the Number Buffer (13_Jun_84) ;----------------------------------- ; 1) This routine fills the Number Buffer. If the number buffer overflows ; then the carry is returned set else its returned cleared. ; 2) Register Usage: ; B -> [Preserved] Maximum for length of Number Buffer ; C -> [Preserved] Current Length of the Number Buffer ; DE -> [Preserved] Pointer into the Number Buffer ; HL -> Pointer into the Terminal.Dat File ; Fill_Numb_Buf: push bc push de ld b,6 ld c,0 ld de,Number_Buffer ;DE:= Start of the Number Buffer FNlp1: ld a,(hl) ;Loop cp "'" ; If ( (Char eq Single Quote) Or jr z,FNdone call White_Space? ; (Char eq White Space) Or jr z,FNdone call End_Line? ; (Char eq Eof/Eol) ) jr z,FNdone FNsk1: call Valid_Number ; If (This isn't a Valid Number) jr nc,FNsk2 pop de pop bc scf ; Flag:= Error ld a,Invalid_Number ; A:= Error Code ret ; Return (Error) FNsk2: ld (de),a ; Number_Buffer:= Current Char inc hl ; Inc Number_Buffer Pointer inc de ; Inc Token_Buffer_Pointer inc c ; Inc Buffer Length djnz FNlp1 ; If (Number Buffer Overflowed) pop de pop bc scf ; Flag:= Error ld a,Number_OverFlo ; A:= Error Code ret ; Return FNdone: ld a,c ld (Number_Length),a ;(Save the Number Length) pop de pop bc ld b,1 ;B:= 1 for Proc_String/Proc_Cursor Loop or a ;Flag:= No Error (clears the carry) ret ;Return ;---------------------------------------------------------------------- ; Check for a Valid Ascii/Ascii-Hex Number (11_Jun_84) ;----------------------------------------------------- ; 1) This routine check if the character in the accm is a number. If it ; is then its converted to a zero based binary number and the carry ; is returned Cleared. Else the number is returned in the accm and ; the carry is returned Set. ; 2) Register Usage: ; A -> Returned w/Number relative to base 0 if valid number ; Valid_Number: cp '0' ;If (Number Lt 0) jr c,VNno ; Quit cp '9' + 1 ;If (Number le 9) jr c,VNyes ; Convert and Exit and 5Fh ;(Force to Upper Case) cp 'A' ;If ( (Number Lt A) Or jr c,VNno cp 'F' + 1 ; (Number Gt F) ) jr nc,VNno ; Quit sub 7 ;Shift Alpha-Number down VNyes: sub '0' ;Shift Number base to 0 or a ;Flag:= its a Number ret ;Return VNno: scf ;Flag:= Not a Number ret ;Return page ;---------------------------------------------------------------------- ; Store a Byte 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 ;---------------------------------------------------------------------- ; Get the Next Line (14_Jun_84) ;------------------------------ ; 1) This routine reads characters until a new-line or and end-of-file ; is read. If the end of file character is read then the carry is ; returned set else its cleared. ; 2) Register Usage: ; A -> Current character ; HL -> Pointer into the source file. ; Get_Next_Line: ld a,(hl) ;Loop Get Character cp End_of_File ; If (Char eq End of File) jr nz,GLsk1 scf ; Flag:= End of File ret ; Return GLsk1: inc hl ; Pointer:= Pointer + 1 cp Cr ; If (Char eq end_of Line) jr nz,Get_Next_Line or a ; Flag:= Not End of File ret page ;---------------------------------------------------------------------- ; Get the Next Token (15_Jun_84) ;------------------------------- ; 1) This routine moves the next token into the Token Buffer, Updates ; the Token Length and Token Type. ; 2) Register Usage: ; A -> Returned equal to the number of characters in buffer ; C -> Counter for Token_Buffer Length ; DE -> Pointer into the dictionary buffer ; HL -> Pointer to the current position in the source file ; Get_Token: call Strip_White ;Remove Leading White Space ld de,Token_Buffer ;DE:= Start of Dict buf ld c,0 ;C:= Counter ; Check For a Number ;------------------- ; ld a,(hl) cp 30h ;If (Char eq Number) jr c,GwSk1 cp 3Ah jr nc,GwSk1 ld a,Token_Number ld (Token_Type),a ld a,0 ld a,(Token_Length) call Fill_Numb_Buf ; Fill the Number Buffer ret ; Return ; Check for a Quoted String ;-------------------------- ; GwSk1: cp "'" ;If (Char eq Single Quote) jr nz,GwLp2 inc hl ; If (Next char eq Quote too) ld a,(hl) cp "'" jr nz,GwLp1 ld (de),a ; Save Quote in Token Buf inc c ; Count it jr GwSk2 GwLp1: ld (de),a ; Else Repeat inc de ; Inc Token Buffer Pointer inc hl ; Inc Source Pointer inc c ; Inc Counter ld a,(hl) call End_Line? ; If (Char eq Eof/Eol) jr z,GwSk2 ; Break cp "'" jr nz,GwLp1 ; Until (Char eq Quote) GwSk2: inc hl ; Pointer:= Next char past Quote ld a,Token_Literal ld (Token_Type),a ld a,c ld (Token_Length),a or a ret ; Read Literal String ;-------------------- ; GwLp2: cp 30h ;Loop If (Char eq Number) jr c,GwSk3 cp 3Ah jr c,GwDone ; Break GwSk3: call White_Space? ; If (Char eq White Space) jr z,GwDone ; Break call End_Line? ; If (Char eq Eof/Eol) jr z,GwDone ; Break cp "'" ; If (Char eq Quote) jr z,Gwdone ; Break ld (de),a ; Token_Buffer:= Current Character inc de ; Token_Pointer:= Token_Pointer+1 inc hl ; Buf_Pointer:= Buf_Pointer + 1 ld a,(hl) inc c ; Counter:= Counter + 1 jr GwLp2 GwDone: ld a,Token_Literal ld (Token_Type),a ;Token Type:= Literal Defintion ld a,c ld (Token_Length),a ;Save the Length or a ret ;Return page ;---------------------------------------------------------------------- ; Strip Leading White Space (11_Jun_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) call White_Space? ret nz inc hl ; Increment the Text Pointer jr Strip_White ;---------------------------------------------------------------------- ; Check for White Space (11_Jun_84) ;---------------------------------- ; 1) This routine Checks if the contents of the Accm is a Space, Tab ; Comma or Line Feed. If there is a match for any of these characters ; then the Z-Flag is returned set else its cleared. ; White_Space?: cp ' ' ;If (Char eq Space, Tab, Lf or Comma) ret z cp Tab ret z cp Lf ret z cp ',' ret ; Return with the Zero Flag Set ;---------------------------------------------------------------------- ; Check for End_of_Line or End_of_File (11_Jun_84) ;------------------------------------------------- ; 1) This routine checks if the Accm is equal to either an End of Line ; or an End of File Mark. If the Accm is equal to either of these ; characters then the Z-Flag is returned Set else its Cleared. ; End_Line?: cp Cr ;If (Char eq end_of Line/File) ret z cp End_of_File ret ; Return with the Zero Flag Set 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 Token Buffer ; HL -> Enter pointing to Start of Dictionary to search ; Dict_Lookup: ld a,(Token_Length) ld c,a ;C:= current token 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,Token_Buffer ; DE:= Start of Token buf SrcLp2: ld a,(de) ; Repeat cp 'a' ; If ( (Number ge a) And jr c,ScrSk3 cp 'z' + 1 ; (Number Le z) ) jr nc,ScrSk3 and 5Fh ; (force upper case) ScrSk3: cp (hl) ; If (no match) jr nz,SrcNxt ; Break inc hl ; inc dict pointer inc de ; inc Token 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 ;---------------------------------------------------------------------- ; 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 page ;====================================================================== ; Verify the Terminal Level (18_Jun_84) ;====================================== ; 1) This routine prints the Description of the Current Level and ; then prompts the user for verification. ; Verify_Level: ld a,(Terminal_Level) or a ;If (Terminal Level eq 0) jr nz,VLsk1 ld c,Bdos_PString ld de,Level_0_Msg call Bdos_Entry ; Print the Level 0 Message jr VLvrf VLsk1: add a,'0' ;Else ld (LevelN),a ; Set the Level Number in Message sub '1' sla a ld e,a ld d,0 ; DE:= (Terminal Level - 1) * 2 ld hl,Level_Table add hl,de ld e,(hl) inc hl ld d,(hl) ; Get a pointer to the Terminal push de ld c,Bdos_PString ld de,Level_n_Msg call Bdos_Entry ; Print the Body of Terminal Message ld c,Bdos_PString pop de call Bdos_Entry ; Print Terminal VLvrf: ld c,Bdos_PString ld de,VlMsg1 call Bdos_Entry ;Print 'Is the current level Ok? (Y/N)' call Yes_or_No ;Get the User's response ret ;Return (Response set in Yes_or_No) page ;====================================================================== ; Build The Console Tranlsation Tables (21_Jun_84) ;================================================= ; 1) This routine builds the Console Translation Tables into Memory. ; Build_Tables: call Setup_Image ;Setup the Character Table ld hl,(Escape_Vector) ;HL:= Start of Table ld a,(Esc_Tbl_Leng) ;A:= Table Length call Move_Down ;Move Translation Strings ld hl,(Control_Vector) ;HL:= Start of Table ld a,(Cnt_Tbl_Leng) ;A:= Table Length call Move_Down ;Move Translation Strings call Fix_CLR ;Fix the Clear Screen Entry if present ld hl,(Save_Pointer) ;HL:= End of Console Translate Image ld de,Memory_Image ;DE:= Start of Console Translate Image or a sbc hl,de ld (Overall_Length),hl ;Save Length of Console translate image ret ;---------------------------------------------------------------------- ; Setup the Character Table Image (18_Jun_84) ;-------------------------------------------- ; 1) This routine sets up an image of the Character Table at the ; beginning of free memory space (Memory_Image). ; Setup_Image: ld de,Memory_Image ld (Esc_Tbl_Pntr),de ld c,$Type_Escape ;C:= Pattern Mask call Build_Trans ;Build Escape Char Translation Table ld (Esc_Tbl_Leng),a ;Save the Escape Table Length ld (Cnt_Tbl_Pntr),de ld c,$Type_Control ;C:= Pattern Mask call Build_Trans ;Build Control Char Translation Table ld (Cnt_Tbl_Leng),a ;Save the Control Table Length ld (Escape_Vector),de ld c,$Type_Escape call Build_Vector ;Build Escape Vector Table ld (Control_Vector),de ld c,$Type_Control call Build_Vector ;Build Control Vector Table ld (Save_Pointer),de ;Save a pointer to the next free space ret page ;---------------------------------------------------------------------- ; Build a Translation Table (20_Jun_84) ;-------------------------------------- ; 1) This routine is used to build the Escape and Control Lookup Tables. ; 2) Register Usage: ; A -> General Purpose - Returned equal to the Table Length ; A' -> Holds the Character (from Get_Type_X) ; B -> Count equal to table length (not including terminator) ; C -> Mask set by calling program ($Type_Control/$Type_Escape) ; DE -> Pointer into table (returned = next free space) ; HL -> Pointer into Dictionary Definitions ; Build_Trans: ld hl,Start_Dict_Def ;HL:= Pointer into the dictionary ld b,0 ;B:= Counter (Table Length) BTlp1: push bc call Get_Type_X ;While (There's an escape char) pop bc jr z,BTsk1 inc b ; Counter:= Counter + 1 ex af,af' ld (de),a ; Save the Character ex af,af' inc de ; Inc Table Pointer jr BTlp1 BTsk1: ld a,0FFh ld (de),a ;Terminate the Lookup Table inc de ;Leave DE pointing to next free space ld a,b ;A:= Table Length ret ;Return ;---------------------------------------------------------------------- ; Build a Vector Table (20_Jun_84) ;--------------------------------- ; 1) This routine is used to build the Escape and Control Vector Tables. ; Build_Vector: ld hl,Start_Dict_Def BVlp3: call Get_Type_X ;While (There's an Escape Char) ret z call Move_Def ; Move the Vector into the table jr BVlp3 page ;---------------------------------------------------------------------- ; Get Next Occurance of Type X in Main Dict Defs (18_Jun_84) ;----------------------------------------------------------- ; 1) Register Usage: ; AF' -> The Translation char if the entry was found ; B -> Temporary storage of the Type Mask from the Dict Def ; C -> Type Mask ; DE -> Counter ; HL -> Pointer into the Dictionary Definitions ; Get_Type_X: ld a,(hl) ;While (Not at the end of the Table) or a ret z ld b,a ; B:= Type Mask inc hl ex af,af' ld a,(hl) ; AF':= Id Byte ex af,af' inc hl ld a,(hl) inc hl or (hl) inc hl jr z,Get_Type_X ; If (Entry has been defined) ld a,c and b ret nz ; Return jr Get_Type_X page ;---------------------------------------------------------------------- ; Move a Translation Definition (18_Jun_84) ;------------------------------------------ ; 1) This routine moves the pointer to a translation string into the ; vector table. ; 2) Register Usage: ; DE -> Pointer into a Vector Table ; HL -> Points to Hi-Byte of Dict Def + 1 ; Move_Def: push hl dec hl dec hl ;HL:= Pointer to Lo-Byte of Dict Def ld a,(hl) ex de,hl ld (hl),a ;Move Lo_Byte into Pointer Table inc hl ex de,hl inc hl ld a,(hl) ex de,hl ld (hl),a ;Move Hi_Byte into Pointer Table inc hl ex de,hl pop hl ret page ;---------------------------------------------------------------------- ; Move a Translation String Down (21_Jun_84) ;------------------------------------------- ; 1) This routine moves the Translation Strings for a Table (ie Control ; or Escape) down to the top of the Console Translation Table Image. ; 2) The Vectors to the Translation Strings are made into offsets ; relative to the start of the Console Translation Structure Base. ; 3) Register Usage: ; A -> Equal to the Table Length on Entry ; B -> Counter (number of entries in the table) ; DE -> Pointer to the Old Location of the Translation String ; HL -> Pointer to New Location of the Translation String ; Move_Down: or a ;If (Table Length eq 0) ret z ; Return ld b,a ;B:= Table Length MDlp1: ld e,(hl) ;Repeat inc hl ld d,(hl) ; DE:= Pointer Source push de push hl ld hl,(Save_Pointer) ; HL:= Destination of String ld de,(Esc_Tbl_Pntr) ; DE:= Base of Translate Struct or a sbc hl,de ex de,hl ; DE:= Offset from Structure Base pop hl ld (hl),d dec hl ld (hl),e ; Update Vector Table inc hl pop de inc hl push hl ; (Save pointer to next vector) ld hl,(Save_Pointer) ; HL:= Pointer to Destination MDlp2: ld a,(de) ; Loop ld (hl),a ; Move a Byte inc hl ; Inc destination pointer inc de ; Inc source pointer cp 0FFh ; Until (Byte eq Terminator) jr nz,MDlp2 ld (Save_Pointer),hl pop hl djnz MDlp1 ;Until (Count eq 0) ret ;Return page ;---------------------------------------------------------------------- ; Fix the CLR Screen Entry in the Escape Table (18_Jun_84) ;--------------------------------------------------------- ; 1) This routine patches the Clear Screen Code Entry in the Escape ; Table (if it is present). This is needed because Adm31's use ; both 1Ah's and '*''s to clear the screen; So, there has to be ; entries in both the Escape and the Control Tables for this code. ; 2) Register Usage: ; A -> General Purpose ; HL -> Pointer into Escape Table ; Fix_CLR: ld hl,(Esc_Tbl_Pntr) ;HL:= Pointer to Start of Escape Table FClp1: ld a,(hl) ;While (Not at the end of the table) cp 0FFh ret z cp Clear_Code ; If (its the Clear Code) jr nz,FCsk1 ld (hl),'*' ; Replace it ret ; Return FCsk1: inc hl ; Inc Table Pointer jr FClp1 page ;====================================================================== ; Check the CP/M version (16_Apr_84) ;=================================== ; 1) This routine checks the CP/M version. It returns with the ; Z flag = 1 if CP/M 3. ; Get_Version: ld c,Bdos_Ret_Ver ;Return version Bdos call call Bdos_Entry ld a,0F0h and l cp 30h ret ;====================================================================== ; Install Definitions in a CP/M 2.2 System (23_Jun_84) ;===================================================== ; Install_Cpm2: call Read_Cpm2_Bios ;Read the Bios into Memory or a ;If (There was an Error) ret nz ; Return call Cpm2_Bias ;Figure the Bias call Cpm2_Level ;Install Terminal Level call Cpm2_Dca ;Install Direct Cursor Addressing Struct call Cpm2_Translate ;Install Console Translation Struct call Write_Cpm2_Bios ;Write the Bios back onto Disk ret ;Return page ;---------------------------------------------------------------------- ; Read the Cp/m 2.2 Bios (23_Jun_84) ;----------------------------------- ; 1) This routine reads the Bios from the system tracks into the ; next free memory space (next free space pointer set in Build_Tables) ; Read_Cpm2_Bios: call Setup_IX ;Set IX to RamdatX and Save the Original ld de,RdBlk_Offset ;DE:= Offset to the RdBlk Address call Get_Bios_Pntr ex de,hl ;HL:= Vector to Read a Block Routine call IR_HL ;Execute the read a block routine ld a,(ix+ErFlag) or a ;If (there were no errors) ret z ; Return ld a,Sys_Read_Err ;Else A:= Error Code ret ; Return IR_HL: jp (hl) ;---------------------------------------------------------------------- ; Write the Cp/m 2.2 Bios (25_Jun_84) ;------------------------------------ ; 1) This routine writes the Bios back to the system tracks. ; Write_Cpm2_Bios: call Setup_IX ;Set IX to RamdatX and Save the Original ld de,WrBlk_Offset ;DE:= Offset to the WrBlk Address call Get_Bios_Pntr ex de,hl ;HL:= Vector to Read a Block Routine call IW_HL ;Execute the Write a Block routine ld a,(ix+ErFlag) or a ;If (There were no errors) ret z ; Return ld a,Sys_Write_Err ;Else A:= Error Code ret ; Return IW_HL: jp (hl) page ;---------------------------------------------------------------------- ; Setup the IX and Initialize Pertinant Values (22_Jun_84) ;--------------------------------------------------------- ; 1) This routine Sets the IX register 2 pages before the start of ; the Bdos and then initializes the essential parameters. ; Setup_IX: ld hl,(Bdos_Entry+1) ;HL:= Pointer to Start of Bdos ld l,0 ;HL:= Pointer to Base of Bios dec h ;HL:= Base Page of Bios - 1 dec h push hl pop ix ;IX:= Base Page of Bios - 1 ld (ix+HstDsk),0 ;Drive:= 0 ld (ix+HstTrk),1 ;Starting_Track:= 1 ld (ix+HstSec),2 ;Starting_Sector:= 2 ld (ix+SecCnt),4 ;Number_of_Sectors_to_Read:= 4 ld (ix+Retry),10 ;Retries:= 10 ld (ix+HstBuf), LOW Disk_Buffer ld (ix+HstBuf+1),HIGH Disk_Buffer ld (ix+ErFlag),0 ;Error_Flag:= Reset ret ;---------------------------------------------------------------------- ; Get One of the Bios Pointers (20_Jun_84) ;----------------------------------------- ; Get_Bios_Pntr: ld hl,(Bios_Entry+1) ;HL:= Pointer to Warm Boot Entry ld l,0 ;HL:= Pointer to Base of Bios call Get_DE_Indr_HL ;DE:= Contents of Addr Pointed to by HL ret ;Return page ;---------------------------------------------------------------------- ; Figure the Memory Bias for Cpm 2.2 (21_Jun_84) ;----------------------------------------------- ; 1) This routine Sets up the Bios Base and the Bios Bias. The Bios ; Base is the starting memory address of where the bios is current ; loaded. The bios Bias is the Starting Memory Address of where the ; bios is intented to be loaded. ; Cpm2_Bias: ld hl,Disk_Buffer ;HL:= Start of the Disk Buffer ld de,Bios_Offset ;DE:= Offset to Bios Start add hl,de ;HL:= Pointer to Start of Cpm Bios ld (Bios_Base),hl ;(save the Base address of the Bios) ld de,WBoot_Offset ;DE:= Offset to Warm Boot Address call Get_DE_Indr_HL ld e,0 ;DE:= Start of Load Location of Bios ld (Bios_Bias),de ;(save the Load address of the Bios) ret ;---------------------------------------------------------------------- ; Install Terminal Level for Cpm 2.2 (21_Jun_84) ;----------------------------------------------- ; Cpm2_Level: ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,RamDatY_Offset ;DE:= Offset to RamDatY Pointer call Get_DE_Indr_HL ;DE:= Start of RamDatY dec de ;(Tlev is at RamDatY - 1) call Apply_Bias_DE ;Adjust DE to Point to current mem loc ld a,(Terminal_Level) ld (de),a ;Install Terminal Level ret ;---------------------------------------------------------------------- ; Install Direct Cursor Addressing Structure for Cpm 2.2 (21_Jun_84) ;------------------------------------------------------------------- ; Cpm2_Dca: ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,DcaPtr2_Offset ;DE:= Offset to Dca Pointer call Get_DE_Indr_HL ;DE:= Start of Dca Structure call Apply_Bias_DE ;Adjust DE to Point to Current Mem Loc ld hl,DcaStrt ;HL:= Start of Newly Built Dca Struct ld bc,Dca_Length ;BC:= Length of Dca ldir ;Move the Dca Structure into place ret page ;---------------------------------------------------------------------- ; Install Console Translation Structure for Cpm 2.2 (23_Jun_84) ;-------------------------------------------------------------- ; Cpm2_Translate: ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,EtblPtr2_Offset ;DE:= Offset to Escape Table Pointer call Get_DE_Indr_HL ;DE:= Control Lookup Table Pointer push de call Adj_Pointers ;Adjust Console Tranlsation Pointers pop de call Adj_Vectors ;Adjust the Char Table Vectors ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,Pool2_Offset ;DE:= Offset to Start of Free Space call Get_DE_Indr_HL ;DE:= Start of Free Space call Apply_Bias_DE ;DE:= Pointer to Position in Memory ex de,hl ;HL:= Pointer to Start of Free Space call Adj_Free_Space ;Adjust the Free Space Pointer or a ;If (Insufficient room for Char Tbl) ld a,Insufficient_FS ret nz ; Return (Error) ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,EtblPtr2_Offset ;DE:= Offset to Escape Table Pointer call Get_DE_Indr_HL ;DE:= Control Lookup Table Pointer call Apply_Bias_DE ;Adjust DE to Point to Current Mem Loc ld hl,(Esc_Tbl_Pntr) ;HL:= Console Xlate Image ld bc,(Overall_Length) ;BC:= Lenght of Conole Xlate Table ldir ;Move the Table Into Place ret page ;====================================================================== ; Install Definitions in a CP/M 3.0 System (21_Jun_84) ;===================================================== ; Install_Cpm3: call Get_Sys_Param ;Setup the Read/Write Parameters or a ;If (there was an error) ret nz ; Return call Read_Sys_File ;Read the Bios from the CPM3.SYS file or a ;If (there was an error) ret nz ; Return ld a,(Terminal_Level) ld (Disk_Buffer + Loff3),a ;Install the Terminal Level ld hl,Disk_Buffer ;HL:= Start of the Disk Buffer ld de,DcaPtr3_Offset ;DE:= Destination of Dca in Disk Buffer call Get_DE_Indr_HL ;DE:= Start of Dca Structure call Apply_Bias_DE ;Adjust DE to Point to Current Mem Loc ld hl,DcaStrt ;HL:= Start of Newly Built Dca Struct ld bc,Dca_Length ;BC:= Length of Dca ldir ;Move the Dca Structure into place call Cpm3_Translate ;Install Console Translation Struct call Write_Sys_File ;Write the Bios to the CPM3.SYS file ret ;Return page ;---------------------------------------------------------------------- ; Calculate System Parameters for Reading/Writing CPM3.SYS (22_Jun_84) ;--------------------------------------------------------------------- ; 1) This routine calculates the starting record and number of ; records of the bios portion of the CPM3.SYS file. Additionally, ; it sets Bios Base (Start of the Disk Buffer), the Bios Bias ; (Starting address of the Bios) and the Top of the Disk Buffer + 1. ; 2) Register Usage: ; A -> Returned 0 for no errors else its an error code ; .. -> all other registers are altered. ; Get_Sys_Param: 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 cp 4 ;If (file was NOT successfully opened) ld a,Sys_Open_Err ; (Error Code) ret nc ; Return ;Read the Header Record ld a,0 ld (FCB_Record),a ;Set the record to use ld de,Disk_Buffer ;DE:= Starting Address of program call Read_Sys_Rec or a ;If (there was an error) ret nz ; Return ld de,Resident_Top ;DE:= Destination ld hl,Disk_Buffer ;HL:= Source ld bc,4 ;BC:= Length ldir ;Move header data to local storage ;Read the Boot Record ld a,(Disk_Buffer+5) ;A:= Page address of Cold Boot Start ld b,a ld a,(Resident_Top) sub b ;A:= Resident_Top - Boot_Start inc a ;Add header/print page sla a ;Convert pages to records dec a ;Convert to base 0 ld (FCB_Record),a ld de,Disk_Buffer ;DE:= Starting Address of program ld (Bios_Base),de call Read_Sys_Rec or a ;If (there was an error) ret nz ; Return ;Figure the Number of Records to Read ld a,(Disk_Buffer+2) ;A:= Starting page of bios ld b,a ld c,0 ld (Bios_Bias),bc ;Save the Bias ld a,(Banked_Top) sub b ;A:= Top Page Bios - Start Page Bios ld d,a ld e,0 ;DE:= Length of Bios in bytes sla a ;Convert to records ld (Bios_Records),a ;(Save the Bios Length in Records) ;Figure the Starting Address/Record of the Bios ld a,(Resident_Leng) ;A:= Number of Pages of Resident Cp/m inc a ;Include the Header/Print Records sla a ;Convert to Records ld (Bios_Start),a ;(Save the Starting Record of the Bios) ld hl,Disk_Buffer add hl,de ;HL:= Top Address of Bios Load ld (Buffer_Top),hl ;(Save the Top of the Buffer) ld a,0 ;Status:= Ok ret ;Return page ;---------------------------------------------------------------------- ; Read the Bios Portion of CPM3.SYS (23_Jun_84) ;---------------------------------------------- ; 1) This routine reads the bios portion of the CPM3.SYS file into ; the disk buffer. ; 2) Register Usage: ; A -> Returned Status ; B -> Record Count ; DE -> Used in Calculating the Next Record ; HL -> Current Dma Address ; Read_Sys_File: ld hl,(Buffer_Top) ;HL:= Top of the Buffer ld a,(Bios_Records) ld b,a ;B:= Length of the Bios in Records ld a,(Bios_Start) ld (FCB_Record),a ;Starting Record of the Bios RSlp1: ld de,Record_Length ;Repeat or a sbc hl,de ; HL:= Dma Address - 1 Record ex de,hl ; DE:= Current Dma Address call Read_Sys_Rec ; Read the Next Record ex de,hl or a ; If (there was an error) ret nz ; Return djnz RSlp1 ;Until (All the records have been read) ret ;---------------------------------------------------------------------- ; Write the Bios Out to Disk (25_Jun_84) ;--------------------------------------- ; 1) This routine writes the bios portion of the CPM3.SYS file from ; the disk buffer and then closes the file. ; 2) Register Usage: ; A -> Returned Status ; C -> Bdos Function Number ; B -> Record Count ; DE -> Used in Calculating the Next Record/Pointer to FCB ; HL -> Current Dma Address ; Write_Sys_File: ld hl,(Buffer_Top) ;HL:= Top of the Buffer ld a,(Bios_Records) ld b,a ;B:= Length of the Bios in Records ld a,(Bios_Start) ld (FCB_Record),a ;Starting Record of the Bios WSlp1: ld de,Record_Length ;Repeat or a sbc hl,de ; HL:= Dma Address - 1 Record ex de,hl ; DE:= Currnet Dma Address call Write_Sys_Rec ; Write the Next Record ex de,hl or a ; If (there was an error) ret nz ; Return djnz WSlp1 ;Until (All the records have been read) ld de,FCB_Sys ld c,Bdos_Close_File ;C:= Close File Function call Bdos_Entry ;Close the CPM3.SYS File ret ;Return page ;---------------------------------------------------------------------- ; Read One Record from the Cp/m System File (23_Jun_84) ;------------------------------------------------------ ; 1) This routine reads one record from the Cp/m system file into ; the address specified by the DE register pair on entry. ; 2) Register Usage: ; A -> Returned Status ; C -> Cp/m Bdos Function Number ; DE -> Dma Address ; Read_Sys_Rec: push de push bc 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 record pop bc pop de or a ;If (There was no error) ret z ; Return ld a,Sys_Read_Err ;Else A:= Error Code ret ; Return ;---------------------------------------------------------------------- ; Write One Record to the Cp/m System File (23_Jun_84) ;----------------------------------------------------- ; 1) This routine writes one record from the Cp/m system file into ; the address specified by the DE register pair on entry. ; 2) Register Usage: ; A -> Returned Status ; C -> Cp/m Bdos Function Number ; DE -> Dma Address ; Write_Sys_Rec: push de push bc 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_Write_Seq ;C:= Write Sequential Function call Bdos_Entry ;Write the record pop bc pop de or a ;If (There was no error) ret z ; Return ld a,Sys_Write_Err ;Else A:= Error Code ret ; Return page ;---------------------------------------------------------------------- ; Install Console Translation Structure for Cpm 3.0 (24_Jun_84) ;-------------------------------------------------------------- ; Cpm3_Translate: ld hl,Disk_Buffer ;HL:= Start address of Bios ld de,EtblPtr3_Offset ;DE:= Offset to Escape Table Pointer call Get_DE_Indr_HL ;DE:= Control Lookup Table Pointer push de call Adj_Pointers ;Adjust Console Tranlsation Pointers pop de call Adj_Vectors ;Adjust the Char Table Vectors ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,Pool3_Offset ;DE:= Offset to Start of Free Space call Get_DE_Indr_HL ;DE:= Start of Free Space call Apply_Bias_DE ;DE:= Pointer to Position in Memory ex de,hl ;HL:= Pointer to Start of Free Space call Adj_Free_Space ;Adjust the Free Space Pointer or a ;If (Insufficient room for Char Tbl) ld a,Insufficient_FS ret nz ; Return (Error) ld hl,(Bios_Base) ;HL:= Start address of Bios ld de,EtblPtr3_Offset ;DE:= Offset to Escape Table Pointer call Get_DE_Indr_HL ;DE:= Control Lookup Table Pointer call Apply_Bias_DE ;Adjust DE to Point to Current Mem Loc ld hl,(Esc_Tbl_Pntr) ;HL:= Console Xlate Image ld bc,(Overall_Length) ;BC:= Lenght of Conole Xlate Table ldir ;Move the Table Into Place ret page ;---------------------------------------------------------------------- ; Adjust the Character Table Pointers (23_Jun_84) ;------------------------------------------------ ; 1) This routine adjusts the Character Table Pointers by using the ; the length values generated in Setup_Image. ; 2) Register Usage: ; A -> General Purpose ; DE -> Enter = Pointer to Escape Translation Table ; HL -> Enter = Location of Pointer to Escape Translation Table ; Adj_Pointers: inc hl inc hl ;(leave HL pointing at the Control Table) push hl ld a,(Esc_Tbl_Leng) inc a ;(add terminator byte) ld l,a ld h,0 ;HL:= Length of Escape Table + 1 add hl,de ex de,hl ;DE:= New Location of Control Table pop hl ld (hl),e inc hl ld (hl),d ;Update Control Lookup Table Addess inc hl push hl ld a,(Cnt_Tbl_Leng) ;A:= Length of Control Vector Table inc a ld l,a ld h,0 ;HL:= Length of Control Table + 1 add hl,de ex de,hl ;DE:= New Location of Escape Vectors pop hl ld (hl),e inc hl ld (hl),d ;Update Escape Vector Table Address inc hl push hl ld a,(Esc_Tbl_Leng) ld l,a ld h,0 sla l rl h ;HL:= Length of Escape Vector Table add hl,de ex de,hl ;DE:= New Location of Control Vectors pop hl ld (hl),e inc hl ld (hl),d ;Update Control Vector Table Address ret ;---------------------------------------------------------------------- ; Adjust the Character Table Vectors (23_Jun_84) ;----------------------------------------------- ; 1) This routine adjusts the Escape and Control Vector Pointers ; 2) Register Usage: ; A -> General Purpose ; DE -> Enter = Pointer to Escape Translation Table ; HL -> Holds current location of vectors to patch ; Adj_Vectors: ld a,(Esc_Tbl_Leng) ;A:= Length of Escape Vector Table ld hl,(Escape_Vector) ;HL:= Current Location of Escape Vectors call Adjust_Vectors ;Adjust the Escape Vectors ld a,(Cnt_Tbl_Leng) ;A:= Length of Control Vector Table ld hl,(Control_Vector) ;HL:= Current Location of Control Vectors call Adjust_Vectors ;Adjust the Control Vectors ret page ;---------------------------------------------------------------------- ; Adjust the Free Space Pointer (23_Jun_84) ;------------------------------------------ ; 1) This routine Moves the Free Space Pointer and adjusts its length. ; 2) Register Usage: ; A -> General Purpose ; DE -> Returned Length from Find_Header ; HL -> Enter Pointing to the Start of the Free Space Pool ; Adj_Free_Space: push hl ld a,0FEh ;A:= Console Translation Table Header call Find_Header pop hl ;(HL:= Pointer to Xlt Header + 2) push hl push de ;(DE:= original length of Xlate Table) ld a,0FFh ;A:= Free Space Pointer Header call Find_Header ex de,hl ;HL:= Free Space Remaining pop de ;DE:= Space Used by Original Xlate Table adä hl,då ;reclaií storage used by original table ld de,(Overall_Length) or a sbc hl,de ex de,hl ;DE:= New Free Space Requirements pop hl ;If (Space Insufficient) ret c ; Return push de ld a,0FEh ;A:= Console Translation Table Header call Find_Header ld de,(Overall_Length) ld (hl),d dec hl ld (hl),e ;Install New translation table length inc hl inc hl add hl,de ld (hl),0FFh ;Install New Free Space Header pop de inc hl ld (hl),e inc hl ld (hl),d ;Update Free Space Remaining ld a,0 ;(Status = no error) ret ;Return page ;---------------------------------------------------------------------- ; Find a Header in the Free Space Pool (21_Jun_84) ;------------------------------------------------- ; 1) This routine finds a header in the free space pool. ; 2) Register Usage: ; A -> Header to Search for ; DE -> Returned equal to the Length of the Data Body ; HL -> On Entry = Start of Free Space; On Exit = Header + 2 ; Find_Header: cp (hl) ;Loop If (Header Matches) inc hl ld e,(hl) inc hl ld d,(hl) ; DE:= Length of Data Body ret z ; Return inc hl ; Else add hl,de ; HL:= Pointer to Next Header jr Find_Header page ;---------------------------------------------------------------------- ; Load the DE register Pair Indirectly Through the HL (20_Jun_84) ;---------------------------------------------------------------- ; 1) This routine Loads the DE register pair Indirectly through the ; HL register pair after adding the entry values of the DE and HL. ; 2) Register Usage: ; DE -> On Entry = Offset; On Exit = (HL + DE) ; HL -> [preseved] Base Address ; Get_DE_Indr_HL: add hl,de ;HL:= Pointer to RamDatY Pointer ld e,(hl) inc hl ld d,(hl) ;DE:= Contents of Addr Pointed to by HL dec hl ret ;Return ;---------------------------------------------------------------------- ; Apply the Bias to the DE Pair (21_Jun_84) ;------------------------------------------ ; 1) This routine adjusts the DE pair. On entry, the DE pair is pointing ; to the actual load address of an object. On exit, the DE pair is ; pointing to the current memory location containing that object. ; 2) Register Usage: ; DE -> Entry: Load Address; Exit: Actual Address ; HL -> Used in figuring the offsets ; Apply_Bias_DE: push hl ex de,hl ;HL:= Load Address Data Object ld de,(Bios_Bias) ;DE:= Load Address Base of Bios or a sbc hl,de ;HL:= Offset from Bios Base ld de,(Bios_Base) ;DE:= Offset to Base of Bios in Memory add hl,de ex de,hl ;DE:= Current Memory address pop hl ret page ;---------------------------------------------------------------------- ; Adjust the Character Table Vectors - General Routine (21_Jun_84) ;----------------------------------------------------------------- ; 1) This routine adjusts the Vector Table (specified by the HL pair) ; by the offset value passed in the DE pair. The Vector Tables are ; built with offsets relative to the base of the Escape Lookup ; Table (see Build_Tables). ; 2) Register Usage: ; A -> Table Length on Entry ; B -> Iteration Counter ; DE -> Load Base Address ; HL -> Pointer into Table ; Adjust_Vectors: or a ;If (The table length is 0) ret z ; Return ld b,a ;B:= Table Length AVlp1: push hl ;Repeat push de ld e,(hl) inc hl ld d,(hl) ex de,hl ; HL:= Relative Vector Location pop de ; DE:= Absolute Base Location add hl,de ex de,hl ; DE:= Absolute Vector Location ex (sp),hl ; HL:= Pointer To Vector ld (hl),e inc hl ld (hl),d ; Update Vector inc hl pop de ; (restore Absolute Base Location) djnz AVlp1 ;Until (the whole table has been adjusted) ret ;Return page ;---------------------------------------------------------------------- ; Get a Yes/No Response from the User (18_Jun_84) ;------------------------------------------------ ; 1) This routine gets a Yes (Y or y) or No (N or n) response from ; the user. ; 2) Register Usage: ; A -> Returned: 0 for YES; 0FFh for NO ; Yes_or_No: 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 ; Goto Warm Boot cp 'Y' ; If (Response is Yes) jr nz,YNsk1 ld a,0 ret ; Return (Ok) YNsk1: cp 'N' ; Else If (Response is No) jr nz,Yes_or_No ld a,0FFh ret ; Return (Not Ok) ;====================================================================== ; Print the Closing Message (26_Jun_84) ;====================================== ; 1) This routine prints the Closing Messages. The First Message ; indicates that the terminal installation is complete; The ; second message tells the User to Press Reset to Make the ; changes effective. ; 2) The Close_Msg_Flag is initialized in Setup_Dat_File. ; Print_Closing: ld de,Closing_1 ;DE:= First Part of Closing Message ld c,Bdos_PString ;C:= Bdos Print String Function call Bdos_Entry ;Print the Message ld a,(Close_Msg_Flag) ;If (Suppression Flag is Set) or a ret nz ; return ld de,Closing_2 ;DE:= Second Part of Closing Message ld c,Bdos_PString ;C:= Bdos Print String Function call Bdos_Entry ;Print the Message ret ;Return ;====================================================================== ; 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,' ' 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,(Output_Radix) ;Repeat divisor:= Current Radix 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,' ' 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,' ' ld c,Bdos_ConOut call Bdos_Entry ;Print a Space ret ;Return page ;---------------------------------------------------------------------- ; Convert from the Current Radix to Binary (13_Jun_84) ;----------------------------------------------------- ; 1) This routine converts a number in the current radix in ascii to ; binary. ; 2) Register Usage: ; BC -> [Preserved] Counter ; DE -> Multiplier (Current Radix) ; HL -> Multiplicand ; RadN_to_Binary: ld hl,0 ld a,(Number_Length) ;If (Buffer is Null) or a ret z ; Return ld e,a ld d,0 ;DE:= Length of Number Buffer ld hl,Number_Buffer ;HL:= Start of Number Buffer add hl,de dec hl ;HL:= End of Number Buffer (Adj 0-Base) ld e,(hl) ld d,0 ex de,hl ;HL:= Last Result dec a ;If (Buffer Length is 1) ret z ; Return push bc ;(Preserve the BC register pair) ld (Temp_Result),hl ex de,hl ;HL:= Pointer to Next Number push hl ld b,a ;B:= Counter ld de,(Input_Radix) TSlp1: pop hl ;Repeat dec hl ld a,(hl) push hl ld l,a ld h,0 ; HL:= Next Digit call Multiply push de ld de,(Temp_Result) add hl,de ld (Temp_Result),hl ; Update Result pop de push hl ld hl,(Input_Radix) call Multiply ; Increment Multiplier ex de,hl pop hl ; (restore result) djnz TSlp1 ;Until (Count eq zero) pop de pop bc ret ;---------------------------------------------------------------------- ; 16 bit Multiply ;---------------- ; 1) This routine multiplies the contents of the HL register by the ; contents of the DE register leaving the result in the HL register. ; 2) Register Usage: ; BC -> [Preserved] Temp Storage ; DE -> [Preserved] Multiplier ; HL -> Multiplicand/Result ; Multiply: push bc push de ;(Save Registers) ld c,l ld b,h ld hl,00000h MuLp1: ld a,b ;While (Count ne zero) or c jr nz,MuSk1 pop de pop bc ; (Restore Registers) ret ; (Return) MuSk1: ld a,b rra ld b,a ld a,c rra ld c,a jr nc,MuSk2 add hl,de MuSk2: ex de,hl add hl,hl ex de,hl jr MuLp1 page ;---------------------------------------------------------------------- ; 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 .sall ;Suppress Macro Listings ;====================================================================== ; 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 ; 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 ;---------------------------------------------------------------------- ; Main Dictionary Definitions ;---------------------------- ; Start_Dict_Def: ; Level 1 Definitions Def_Clear: db $Type_Control or $Type_Escape db Clear_Code 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 End_Dict_Def: db 0 ;Terminator for the Compact Routine 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 Esc ;Escape Character Def_Space: db $Type_Char ;Type:= Non Printing Character db ' ' ;Space Def_Levelº dâ $Type_Level ;Type:= Level Definition db 0 page ;---------------------------------------------------------------------- ; Error Code Tables and Message Strings (25_Jun_84) ;-------------------------------------------------- ; ; Error Message String Lookup Table ;---------------------------------- ; Error_Table: db Dat_Open_Error ;Cannot open the Termianl Definition File dw ODEmsg db Dat_Read_Err ;Cannot Read the Terminal Definition File dw DREmsg db Token_Overflow ;Token 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 db Invalid_Number ;Invalid Char in Numeric String dw BNmsg db Number_Overflo ;Literal Numeric String is too Long dw NOmsg db Dca_OverFlo ;Direct Cursor Address String too Long dw DCmsg db Insufficient_FS ;Not Enough Room for Translation Table dw IRmsg db Sys_Open_Err ;Unable to Open System file on Disk dw SOmsg db Sys_Read_Err ;Unable to read System from the Disk dw SRmsg db Sys_Write_Err ;Unable to Write System to the Disk dw SWmsg End_Table: Max_Error equ ( (End_Table - Error_Table)/3 ) + 1 page ; Error Message Strings (25_Jun_84) ;---------------------------------- ; ODEmsg: db 'Cannot Open the Terminal Definitions file $' DREmsg: db 'Cannot Read the Terminal Definition File $' DOmsg: db 'Token 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 $' BNmsg: db 'Invalid Char in Literal Numeric String $' NOmsg: db 'Literal Numeric String is too Long $' DCmsg: db 'Direct Cursor Address String too Long $' IRmsg: db 'Not Enough Room for the Character Translation Table $' SOmsg: db 'Unable to Open System file on Disk $' SRmsg: db 'Unable to Read System from the Disk $' SWmsg: db 'Unable to Write System to the Disk $' 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 Tab,' Please enter the Letter of Your Choice $' CrLf: db Cr,Lf,'$' VrMsg1: db Cr,Lf,Lf db Tab,' Is $' VrMsg2: db ' the correct choice? (Y/N) $' VlMsg1: db Cr, Lf,Lf,Lf,Lf db Tab,' Is the current level Ok? (Y/N) $' Level_0_Msg: db Cr,Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf db Tab,'The CP/M SYSTEM diskette will not be installed for your' db Cr,Lf db Tab,'terminal. You must install some of the application programs' db Cr,Lf db Tab,'(i.e. WordStar and LogiCalc) yourself. In addition, the' db Cr,Lf db Tab,'Micro-Menus will not appear as they should on the screen.' db Cr,Lf db Tab,'Before confirming this selection, check to see if your' db Cr,Lf db Tab,'terminal can emulate any of those on the selection Menu. If' db Cr,Lf db Tab,'it can, you will find it more convenient to use your system.' db Cr,Lf,'$' Level_n_Msg: db Cr,Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf, Lf,Lf,Lf,Lf, Lf,Lf db Tab,'You have a Level ' LevelN: db '1 terminal. All programs supplied by Morrow' db Cr,Lf db Tab,'Designs are pre-installed for your terminal. Any programs' db Cr,Lf db Tab,'not supplied by Morrow Designs must be installed for' db Cr,Lf,'$' Level1: db Tab,'an ADM-3A terminal. $' Level2: db Tab,'a SOROC IQ-120 terminal. $' Level3: db Tab,'an ADM-31 terminal. $' Level4: db Tab,'an MDT-60/MDT-70 terminal. $' Closing_1: db Cr,Lf,Lf,Lf,Lf,Tab db 'The Terminal Installation is Now Complete' db Cr,Lf,'$' Closing_2: db Tab db 'Press Reset to Make the Changes Effective Immediately' db Cr,Lf,'$' page ;====================================================================== ; Local Data Area (25_Jun_84) ;---------------------------- ; ; Local Fcb's ;------------ ; FCB_Dat: db 0,'TERMINALDAT',0 ;Fcb name field ds 20,0 ;Blank file remainder of FCB FCB_Sys: db 0,'CPM3 SYS',0 ;Fcb name field ds 19,0 ;Blank file remainder of FCB FCB_Record: db 0 ;Current Record Field of FCB ; Title Processing Storage ;------------------------- ; Max_Titles: db 0 ;Total Number of Titles Title_Pointer: dw 0 ;Pointer into the title buffer Title_Buffer: ds 60h,0 ;Title Buffer 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 ; Line Processing Storage ;------------------------ ; 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 Temp_Buffer: dw 0 ;Pointer to end of Memory_Image Token_Type: db 0 ;Type of Token Token_Length: db 0 ;Length of the Dictionary buffer Token_Buffer: ds 20h ;Dictionary buffer Number_Buffer: ds 6,0 ;Buffer for Literal Numeric Strings Number_Length: db 0 ;Length of the Number Buffer Temp_Result: dw 0 ;Temporary Result used in Radix Conversion page ; Other Storage ;-------------- ; Save_Pointer: dw 0 ;Save Location for a Word Esc_Tbl_Leng: db 0 ;Length of Escape Char Translate Table Cnt_Tbl_Leng: db 0 ;Length of Control Char Translate Table Overall_Length: dw 0 ;Overall Length of Console Translate Table Dca_Level: db 0 ;Current Dca Level (Start, Mid or End) Dca_Offset: db 0 ;Current Dca String Length Output_Radix: dw 10 Input_Radix: dw 10 Bios_Base: dw 0 ;Actual Memory Address of the Bios Bios_Bias: dw 0 ;Intended Load Address of the Bios Close_Msg_Flag: db 0 ;Suppress Push Reset Part of Closing Message Level_Table: dw Level1 ;Lookup Table For Terminal Types dw Level2 dw Level3 dw Level4 ; CPM3.SYS file Parameters ;------------------------- ; Resident_Top: db 0 ;Top page + 1 of Resident Cp/m Resident_Leng: db 0 ;Length of Resident Cp/m Banked_Top: db 0 ;Top page + 1 of Banked Cp/m Banked_Leng: db 0 ;Length of Banked Cp/m Bios_Records: db 0 ;Length of the Bios in Records Bios_Start: db 0 ;Starting Record of the Bios Buffer_Top: dw 0 ;Last Address of Disk Buffer + 1 page ; Character Table Storage ;------------------------ ; Terminal_Level: db 0 ;Terminal definition level DcaStrt: db Esc,'=' ds Dca_Len-2,0FFh ;Dca Prefix String DcaMid: ds Dca_Len,0FFh ;Dca Seperator String DcaEnd: ds Dca_Len,0FFh ;Dca Terminator String Esc_Lvl: db 0 ;Escape processing level Offset1: db 0 ;First Character Offset Offset2: db 0 ;Second Character Offset Order: db 0 ;Flag Byte (0-Row/Col, 1-Bin/Asc) Dca_Length equ $ - DcaStrt ;Overall Length of Dca Struct Esc_Tbl_Pntr: dw 0 ;Pointer to Start Escape Lookup Table Cnt_Tbl_Pntr: dw 0 ; " " " Control Lookup Table Escape_Vector: dw 0 ;Vector to start of the Escape Table Control_Vector: dw 0 ;Vector to start of the Control Table Memory_Image: db 0 ;Label for start of buffer end