Title Function Key Translation for the MD11 (6_Aug_84) ; ; Copyright 1984 ; Morrow Designs, Inc. ; San Leandro, Ca. ; John Zalabak ; .z80 .sall ;Suppress listings of the expanded macro definitions aseg org 0100h ; This program translates a source file residing on the disk ; into a table residing in the curently running system. The table in ; the system is used to intercept Function Keys, input from the console, ; into arbitrary length strings. These strings may contain any code ; that can be generated from the console. For example, the standard ; function key sequences (defined in the bios assmbly source code) ; include the output string HELP in response to the help key, a control_H ; iî responså tï thå control_UÐ arro÷ keù a null (nothing output) for ; á Shifted_DOWÎ arrow. page 64 ; Indeø tï Routineó (6_Aug_84) ;----------------------------- ; ; Maiî_Linå_Keù Maiî linå oæ thå functioî keù program ; ; Save_Param Save the Input Parameters ; Opeî_á_Filå Openó thå inpuô keù file ; ; Parså_á_Linå Parseó thå nexô linå froí thå keù inpuô file ; Put_Init_Line Put the Initialization Line Out to the Terminal ; Geô_Chaiî_Filå Chainó tï thå filå specifieä oò tï warí boot ; Get_Switch Read & Translate a switch definition line ; ; Code_to_Key Read & Translate Key Code; enter into Key Table ; Def_to_Temp Move a Function Key Definition into Temp Buffer ; Temp_to_Key Move the Temp Buffer definiton into Key Table ; ; Non_to_Dict_Buf Moves Non_Printing Key Name into Dict_Buffer ; Key_to_Dict_Buf Moves Function key's name into Dict_Buffer ; Lookup_Key_Name Looks for Dict_Buffer name in key dictionary ; Update_Key_Table Enter a byte into the Key Table ; ; Get_Next_Line Reads input key file until end of line/file ; Get_Non_White Reads input key file until Non Whitespace encountered ; Force_Upper_Case Force Character to Upper Case & Mask Parity ; Put_Back_Char Puts one character back into the key input file ; Get_Next_Char Gets the next character from the key input file ; ; Inject_Keys Inject Function Keys ; Install_Switches Install Switch Line Settings ; Get_Pointers Get Pointers into the Free Space ; Find_a_Code Find a Function Key Code ; Get_Version Check CP/M version ; Geô_thå_Pooì Geô thå Free Space Pooì ; Put_the_Pool Restore the Free Space Pool ; Inject_Command Inject the Command Line into the Ims Buffer ; Translate_Ims Translate Special Ims Characters ; Call_Cold_Boot Call the Bios Cold Boot Entry Point ; Move_a_Block Move a block of memory ; ; Report_Errors Reports errors on the console ; Print_Line_Number Print the Line number ; ; Data Areas: ; Error Code Tables and Message Strings ; Key Dictionary Macro Definitions ; Key Dictionary ; General Data Area page ;---------------------------------------------------------------------- ; Equates (6_Aug_84) ;------------------- ; Rev equ 20h ;Revision 2.0 ;Bios/Bdos Equates Bios_Entry equ 0 ;Bios Entry Point Bdos_Entry equ 5 ;Bdos Entry Vector Location Bdos_ConOut equ 2 ; Console Output Function 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_SelDsk equ 14 ; Select a Drive 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_Get_Drive equ 25 ; Return the Current Drive Number Bdos_Set_DMA equ 26 ; Set the DMA Address Bdos_Get_User equ 32 ; Get/Set the User Number ;Non Printing Ascii Equates EOF equ 1Ah ;End of File Character Escape equ 1Bh ;Escape Cr equ 0Dh ;Carriage Return Lf equ 0Ah ;Line Feed Tab equ 09h ;Tab Space equ 20h ;Space PCr equ 8Dh ;pause carriage return ;IMS Response to Console Input Status Checks when IMS is active Slow equ 9Dh ;Console input status false Fast equ 9Fh ; " " " true ;Error Codes Missing_Key_Def equ 0FFh ;No Key Definition Bad_Key_Name equ 0FEh ;Missing Function Key Name Invalid_Key equ 0FDh ;Invalid Function Key Assignment Def_too_Long equ 0FCh ;Key Definition String is too long Temp_Overflow equ 0FBh ;Temp buffer overflowed Key_Overflow equ 0FAh ;Local Function Key Table Overflowed Table_too_Big equ 0F9h ;Function Key Table is too large No_Key_File equ 0F8h ;No Key file name Bad_Key_File equ 0F7h ;Can't open the key file Disk_Read_Error equ 0F6h ;Error occured in a disk read operation Unexpected_End equ 0F5h ;Unexpected End (Eol or Eof) Bad_Definition equ 0F4h ;Illegal Character Dict_Overflow equ 0F3h ;Dictionary Buffer has overflowed Bad_Switch equ 0F2h ;Illegal spec. in a switch definition line ;File Control Block Definitions Fcb1 equ 5Ch ;Start of the 1st FCB generated by the CCP Fcb2 equ 6Ch ; " " " 2nd FCB " " " " Fcb1_Extent equ Fcb1+9 ;Offset to the start of the FCB's Extent Fcb1_cr_Field equ Fcb1+32 ;Offset to the current record field ;Extended Bios Function Call Codes F_Write_Sys equ 1 ;Write to system memory F_Get_RamDatY equ 2 ;Read RamDatY and Apif F_Get_Pool equ 8 ;Get the free space pool F_Inject_Ims equ 11 ;Inject a string into the Ims Buffer F_Get_CFlag equ 17 ;Modify contents of CFlag with the E register ;Free Space Id Codes Id_FS equ 0FFh ;Id of the Free Space Pointer Id_IMS equ 0FDh ;Id of the IMS buffer Id_FC equ 0FCh ;Id of the Function Key Table ;Length defintions Record_Length equ 80h ;Length of one record Max_Temp_Length equ 100h ;Maximum Length of the Temp Buffer Max_Dict_Length equ 10h ; " " " the dictionary buffer Max_Rec_Length equ 80h ; " " " a Record Max_Key_Length equ 400h ; " " " the Local Key Table Max_Pool_Length equ 800h ; " " " the Free Space Pool Buffer Max_Stack_Space equ 20h ; " " " the main stack ;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 Pool_Offset equ 43h ;Offset -> Pool Pointer from Bios Base (Cpm2) RamDatY_Offset equ 3Fh ;Offset -> RamDatY Pointer from Bios Base (Cpm2) SFlag_Offset equ 7 ;Offset -> SFlag to RamDatY base (Cpm2 negative off) CFlag_Offset equ 12h ;Offset -> CFlag to RamDatY base (Cpm3) $FunAct_Cpm2 equ 2 ;Mask for Fast_Slow Bit in SFlag (Cpm2) $FunAct_Cpm3 equ 4 ; " " " " " CFlag (Cpm3) page ;====================================================================== ; Main Line Key (3_Aug_84) ;========================= ; Main_Line_Key: ld sp,Main_Stack ;Initialize the stack pointer call Save_Param ;Save the input parameters or a ;If (There were input parameters) jr nz,KdSk1 call Open_a_File ; If (file can't be opened) or a jr nz,KeyErr ; Goto Error Return KdLp1: call Parse_a_Line ; Repeat Parse an input line or a jr z,KdLp1 ; Until (Parse_Result ne Continue) cp EOF ; If (Parse_result ne End of File) jr nz,KeyErr ; Goto Error Return KdSk1: call Inject_Keys ;Inject Function Key Table or a ;If (keys were NOT installed) jr nz,KeyErr ; Goto Key Error Return call Inject_Command ;Inject the New Command Line jr KeyOk KeyErr: call Report_Errors ;Report the error KeyOk: call Restore_Param ;Restore Current Drive and User jp Bios_Entry ;Warm Boot page ;====================================================================== ; Save the Input Parameters (3_Aug_84) ;===================================== ; 1) This routine saves the command tail, located in the default dma ; buffer at location 80h, minus the first word on the line. The first ; word on the line is the key file name which is NOT passed on to the ; chain file. The first 13 bytes of the second FCB are also saved. ; 2) Register Usage: ; BC -> Current Line Length ; DE -> destination pointer ; HL -> Pointer into default dma and source pointer ; Save_Param: ld hl,Default_Dma ;HL:= Pointer into default dma buffer ld a,(hl) oò a ;if (Command line is zero length) jr nz,SpSk1 ld a,0FFh ; A:= No Input Parameters jr SpDone ; Goto Parameter Setup ;Remove Leading White Space SpSk1: ld b,a ;Else B:= Line Length SpLp1: inc hl ; Repeat Move Pointer to next char ld a,(hl) cp Space ; If ((Char ne Space) and jr z,SpSk2 cp Tab ; (Char ne Tab) ) jr nz,SPlp2 ; Break SpSk2: djnz SpLp1 ; Until (line length - 1 eq zero) ld a,0FFh ; A:= No Input Parameters jr SpDone ; Goto Parameter Setup ;Remove the first word from the line SpLp2: dec b ; While (Line length ne 0) jr z,SpLp3 inc hl ld a,(hl) cp Space ; If ((Char eq Space) or jr z,SpLp3 cp Tab ; (Char eq Tab) ) jr nz,SpLp2 ; Break ;Strip the Leading White Space SpLp3: dec b ; Repeat Dec Counter inc hl ; Inc Line Pointer ld a,(hl) cp Space jr z,SpLp3 cp Tab jr z,SpLp3 ; Until ((Not Space) & (Not Tab)) cp Cr jr z,SpDone cp lf jr z,SpDone cp 0 jr z,Spdone ;Save the remainder of the input line ld a,b ld (Old_Input_Line),a ; save the line length or a ; If (Line length ne 0) jr z,SpDone cp 1 ; If ((Length eq 1) and jr nz,SpSk3 ld a,(hl) ; (1st char eq '\')) cp '\' jr nz,SpSk3 ld c,Bdos_PString ld de,Key_Rev_Msg call Bdos_Entry ; Print the Rev Number jr SpDone SpSk3: ld de,Old_Input_Line+1 ; DE:= Destination (save line) ld c,a ld b,0 ; BC:= Byte Count ldir ; Save the old input line ld a,0 ; Returned Status:= Ok ;Save the Current User Area SpDone: push af ld e,0FFh ;E:= Get User Number Function ld c,Bdos_Get_User ;C:= Bdos Get/Set User Number Function call Bdos_Entry ;Get the Current User Number ld (Entry_User),a ;Save the Current User Area ;Save the Current Drive ld c,Bdos_Get_Drive ;C:= Bdos Get Current Drive Number call Bdos_Entry ;Get the Current Drive ld (Entry_Drive),a ;Save the Current Drive pop af ;A:= Input Parameters Present ret ;Return page ;====================================================================== ; Open a File (27_Jul_84) ;======================== ; Open_a_File: ld a,(Fcb1_Extent) ;If (the extent is undefined) cp Space jr nz,OFSk1 ld hl,Default_Ext ; HL:= Source (Default Extent) ld de,Fcb1_Extent ; DE:= Destination (Crn Fcb Ext) ld bc,3 ; BC:= Length ldir ; Install Default Extent ('KEY') OFSk1: ld a,0 ld (Fcb1_cr_Field),a ;Clear the current record field ld c,Bdos_Set_DMA ;C:= Set DMA Address Funtion Number ld de,Record_Buffer ;DE:= Pointer to start of Record Buffer call Bdos_Entry ;Set the Dma Address call Attempt_Open ;Open on Current Drive -- Current User or a ;If (Open Successful) ret z ; Return ld e,0 ;E:= User 0 ld c,Bdos_Get_User ;C:= Bdos Get User Number call Bdos_Entry ;Set the Current User Area to 0 call Attempt_Open ;Open on Current Drive -- User 0 or a ;If (Open Successful) ret z ; Return ld e,0 ;E:= Drive 0 ld c,Bdos_SelDsk ;C:= Bdos Select Disk Function call Bdos_Entry ;Select Drive A: call Attempt_Open ;Open on Drive 0 -- User 0 ret ;Return (Status set in Attempt Open) ; Attempt to Open the File ;------------------------- ; Attempt_Open: ld c,Bdos_Open_File ;C:= Open a File Function Number ld de,Fcb1 ;DE:= Pointer to Default FCB call Bdos_Entry ;Open the file cp 0FFh ;If (Open was Successful) ld a,0 ; Returned Status to Ok ret nz ; Return ld a,Bad_Key_File ;Else Returned Status to Failure ret ; Return page ;====================================================================== ; Parse a Line (27_Jul_84) ;========================= ; 1) This routine parses one line. ; 2) It Returns an EOL to continue and an EOF to Stop. ; 3) Valid Line Types: ; blank lines contain only whitespace ; ; comment lines start with a semi-colon ; # switch setting lines start with an octathorpe ; other function key definitions ; Parse_a_Line: call Get_Non_White ;Repeat Strip White_Space cp EOF ; If (Char eq End of File) ret z ; Return cp ';' ; If (Char eq Comment) jr nz,PLsk1 call Get_Next_Line ; Get the Next Line jr Parse_a_Line Plsk1: cp Cr jr z,Parse_a_Line ;Until ((Char ne Comment)&(Char ne Cr)) cp '%' ;If (Char eq Initialization Line) jr nz,PLsk11 call Put_Init_Line ; Print the Initialization String ret ; Return PLsk11: cp '*' ;Else If (Char eq File Spec) jr nz,PLsk2 call Get_Chain_File ; Get the Chain File Spec ret ; Return PLsk2: cp '#' ;Else If (Char eq Switch Setting Line) jr nz,PLsk3 call Get_Switch ; Decode the Switch Setting ret ; Return PLsk3: call Code_to_Key ;Else Move Key Code into Key Table or a ; If (Return_Status ne Continue) ret nz ; Return call Def_to_Temp ; Get Key Definition or a ; If (Return_Status ne Continue) ret nz ; Return call Temp_to_Key ; Move Temp Buffer into Key Table ret ; Return page ;---------------------------------------------------------------------- ; Put the Initialization Line Out to the Terminal (27_Jul_84) ;------------------------------------------------------------ ; 1) This routine reads the remainder of the current line into the ; Temp_Buffer; Then, the contents of the Temp Buffer are printed. ; 2) Null Length Definitions are ok. ; Put_Init_Line: call Get_Non_White ;Remove Leading White Space call Put_Back_Char ;(Replace the First Character) call Def_to_Temp ;Move the Line to the Temp Buffer or a ;If (There was an Error) ret nz ; Return ld a,(Temp_Length) ;If (Line Length is 0) or a ret z ; Return call Get_Version ;If (This is a Cpm_3 System) jr nz,PiSk1 ld e,0 ; E:= New Value of CFlag ld a,F_Get_CFlag ; A:= Get CFlag Function Number call Call_Cold_Boot ; Call Bios Cold Boot Entry Point ld e,d ; E:= Current Value of CFlag push de ; (Save original value of CFlag) PiSk1: ld hl,Temp_Buffer ;HL:= Start of Temp Buffer ld b,a ;B:= Temp Line Length ld c,Bdos_ConOut ;C:= Console Output Function PiLp1: push bc ;Repeat push hl ld e,(hl) ; E:= The next character call Bdos_Entry ; Print the Character pop hl pop bc inc hl ; Increment the Buffer Pointer djnz PiLp1 ;Until (whole line has been printed) call Get_Version ;If (This is a Cpm_3 System) jr nz,PiSk2 pop de ; E:= Original Contents of CFlag ld a,F_Get_CFlag ; A:= Get CFlag Function Number call Call_Cold_Boot ; Call the Bios Cold Boot Entry Point PiSk2: ld a,0 ;A:= Ok Return Status ret ;Return page ;---------------------------------------------------------------------- ; Get Chain File (6_Aug_84) ;-------------------------- ; 1) This routine inserts the chain file in front of the save image ; of the command tail (if there was one). ; Get_Chain_File: call Def_to_Temp ;Move the Chain File into the Temp Buffer ld a,(Temp_Length) ;If (this was a blank line) or a ret z ; Return ld e,a ld d,0 push de ;(Stack:= Temp Length) ;Move the Old_Input_Line Up to accomidate the Chain Command ld hl,Old_Input_Line ;HL:= Pointer to Length Old Input Line ld a,(hl) ;If (the Line Length gt 0) or a jr z,GcSk2 ld c,a ld b,0 ; BC:= Length of Old Input Line inc a ld (hl),a ; Inc Line Length for Leading ' ' inc hl ex de,hl ; DE:= Old Input Line add hl,de ; HL:= Old Input Line + Cmnd Len push hl ; (Stack:= Pointer to leading ' ') inc hl ; Make Room for Leading Space ex de,hl call Move_a_Block ; Move the Old Input Line Up pop hl ld (hl),' ' ; Insert Leading Space ;Insert the New Chain Command GcSk2: pop bc ld de,Old_Input_Line ;DE:= Pointer to Length of Old Input Line ld hl,Temp_Buffer ;HL:= Source is Command Name Buffer ld a,(de) add a,c ld (de),a ;Update the Old Input Line Length inc de ;DE:= Start of Old Input Line call Move_a_Block ;Move the New Command into place call Get_Next_Line ld a,0 ret page ;---------------------------------------------------------------------- ; Read & Translate a switch definition line (26_Apr_84) ;------------------------------------------------------ ; 1) This routine translates the switch values passed on a switch ; setting line. Currently (26_Apr_84) the only switch setting is ; whether a true or a false is returned to console status queries ; when the ims is active. ; Get_Switch: call Get_Non_White ;Remove Leading White Space cp '_' ;If (Char ne Special) jr z,GsSk1 ld a,Bad_Switch ; Error_Code:= Illegal switch ret ; Return GsSk1: call Put_Back_Char ;(Replace the underscore) call Non_to_Dict_Buf ;Move Symbol to Dict_Buf or a ;If (Unexpected End Err) ret nz ; Return (Error) ld hl,Non_Dictionary ;HL:= Start of Non_Dict call Lookup_Key_Name ;Find key in dictionary or a ;If (Key not defined) ret nz ; Return (Error) ld a,(hl) cp Slow ;If (Console status false w/ims active) ld a,0 ; A:= 0 jr z,GsSk2 ;Else ld a,0FFh ; A:= FF GsSk2: ld (Fast_Slow),a ;Save the switch value ld a,0 ;Returned status:= OK ret ;Return page ;---------------------------------------------------------------------- ; Code to Key (28_Feb_84) ;------------------------ ; 1) This routine gets the key definition string, translates it and ; then moves it into the Key Table. ; Code_to_Key: ld bc,2 ;If (Char eq Control) cp '^' ; BC:= Index to control column jr z,GkSk1 dec bc ;Else If (char eq Shifted) cp '~' ; BC:= Index to shifted column jr z,GkSk1 dec bc ;Else BC:= Index to UnShifted column call Put_Back_Char ; put character back into record GkSk1: push bc call Key_to_Dict_Buf ;Move Function Key Name into its buffer or a ;If (Def not found) ret nz ; Return Error ld hl,Key_Dictionary ;HL:= Start of the function key dict. call Lookup_Key_Name ;Find the key in the dictionary pop bc or a ;If (Key not defined) ret nz ; Return add hl,bc ;HL:= Pointer to key code ld a,(hl) ;A:= Key Code cp Null ;If (Invalid Function Key Assignment) jr nz,GkSk5 ld a,Invalid_Key ; Set the returned error status ret ; Return GkSk5: call Update_Key_Table ;Enter the key code into local buffer or a ;If (Return_Status eq Error) ret nz ; Return (table overflowed) ld a,(Number_of_Keys) inc a ld (Number_of_Keys),a ;Increment the number of keys defined ld a,0 ;Set Returned Status to OK ret page ;---------------------------------------------------------------------- ; Definition to Temp Buffer (4_Mar_84) ;------------------------------------- ; 1) This routine builds the remainder of the current line into the ; the temp buf. The line is terminated either by a carriage return ; or an End of File character. The line length is returned in the ; location Temp_Length. ; 2) Several special symbols are recognized. ; ; Ends the line (comment follows) ; ^ The character that follows is a control character ; \ The character that follows is to be taken literally ; _ Preceeds the special symbols for non-printing chars ; Def_to_Temp: ld a,0 ld (Temp_Length),a ;Initialize temp buffer length to 0 call Get_Non_White ;Strip Leading White Space DTlp1: cp Cr ;While ( (char ne End of Line) and jr z,DTend cp EOF ; (char ne End of File) ) jr nz,DTsk1 DTend: call Put_Back_Char ; (Put back Cr or EOF) ld a,0 ; (Set Return Status OK) ret ; (Return) DTsk1: cp ';' ; If (Char eq Comment) jr nz,DTsk2 call Get_Next_Line ; Get the Next Line ld a,0 ret DTsk2: cp '\' ; If (char eq Literal) jr nz,DTsk3 call Get_Next_Char ; Get the next character cp EOF ; If ( (End or File) or jr z,DTsk21 cp Cr ; (End of Line) ) jr nz,DTsto DTsk21: ld a,UnExpected_End ; Set Error Status ret ; Return DTsk3: cp '^' ; If (char eq Control) jr nz,DTsk4 call Get_Next_Char ; Get the next character call Force_Upper_Case ; Force it to upper case cp 40h ; If (Char in range) jr c,DTsk31 cp 60h jr nc,DTsk31 and 1Fh ; Convert to control jr DTsto DTsk31: ld a,Bad_Definition ; Else Set Error Status ret ; Return DTsk4: cp '_' ; If (Char eq Special) jr nz,DTsto call Put_Back_Char ; (Replace the underscore) call Non_to_Dict_Buf ; Move Symbol to Dict_Buf or a ; If (Unexpected End Err) ret nz ; Return (Error) ld hl,Non_Dictionary ; HL:= Start of Non_Dict call Lookup_Key_Name ; Find key in dictionary or a ; If (Key not defined) ret nz ; Return (Error) ld a,(hl) ; Get the key code DTsto: ld c,a ; (Save Char in C register) ld a,(Temp_Length) ld e,a ld d,0 ; DE:= Offset into temp buffer ld hl,Temp_Buffer add hl,de ; HL:= Pointer into Temp Buffer ld (hl),c ; Temp_Buffer(offset):= char ld a,e inc a ; If (temp buffer overflowed) jr nz,DTsk5 ld a,Temp_Overflow ; Set Return Error Status ret ; Return DTsk5: ld (Temp_Length),a ; Temp_Length:= Temp_Length + 1 call Get_Next_Char ; Get Next Character from record jr DTlp1 ret ;Return page ;---------------------------------------------------------------------- ; Temp to Key (2_Mar_84) ;----------------------- ; 1) This routine moves the contents of the Temp Buffer into Key Table. ; 2) If there was room for the whole Temp Buffer then the accm is ; returned equal to zero; Else its returned with the no room error ; code (Key_Overflow) generated in Update_Key_Table. ; Temp_to_Key: ld a,(Temp_Length) ld b,a ;(save length in BC) call Update_Key_Table ;Enter the Def Length into local buffer or a ;If (Return_Status eq Error) ret nz ; Return (table overflowed) ld a,b ;If (length is zero) or a ret z ; Return (Status equal OK) ld hl,Temp_Buffer TKlp1: ld a,(hl) ;Repeat Get next character from temp buffer inc hl ; Increment temp buffer pointer push hl call Update_Key_Table ; Enter the character pop hl or a ; If (Key Table has overflowed) ret nz ; Return djnz TKlp1 ;Until (character count is zero) ld a,0 ;Set Return Status to OK ret ;Return page ;====================================================================== ; Non_Printing Key to Dictionary Buffer (2_Mar_84) ;================================================= ; 1) This routine Moves a key name into the dictionary buffer. ; 2) This routine expects to read an Undescore followed by a three ; character sysmbol name for a non_printing character. ; 3) Before entering this routine the underscore has already been ; read and then put back into the input stream. ; Non_to_Dict_Buf: ld a,4 ;(length is always '_' + 3 char symbol) ld (Dict_Length),a ;Set the dictionary buffer Length ld b,a ;B:= Char Counter ld de,Dict_Buffer ;DE:= Start of temp Buffer NDlp1: push bc ;Repeat push de call Get_Next_Char ; Get the next character pop de pop bc cp Cr ; If ( (Char eq end of line) or jr z,NDerr cp EOF ; (Char eq EOF) ) jr nz,NDsk1 NDerr: ld a,UnExpected_End ; Set Error Return Status ret ; Return NDsk1: call Force_Upper_Case ; Force character to upper case ld (de),a ; Store a character inc de ; Increment the Storage Pointer djnz NDlp1 ;Until (count eq 0) ld a,0 ;Set Returned Status ret ;Return page ;---------------------------------------------------------------------- ; Key to Dictionary Buffer (2_Mar_84) ;------------------------------------ ; 1) This routine Moves a key name into the dictionary buffer. ; Key_to_Dict_Buf: call Get_Non_White ;Strip Leading White Space ld b,0 ;B:= Char Counter ld de,Dict_Buffer ;DE:= Start of temp Buffer KNlp1: cp Space ;Loop If (Char eq Space) jr z,KNDone ; Break cp Tab ; If (Char eq Tab) jr z,KNDone ; Break cp Cr ; If (Char eq end of line) jr z,KNDone ; Break cp Lf ; If (Char eq Line Feed) jr z,KNDone ; Break cp EOF ; If (Char eq EOF) jr z,KNDone ; Break call Force_Upper_Case ; Force character to upper case ld (de),a ; Store a character inc de ; Increment the Storage Pointer inc b ; Increment the char counter ld a,Max_Dict_Length cp b ; If (Dict_Buffer has Overflowed) jr nz,KNsk1 ld a,Dict_Overflow ; Set Return Error Status ret ; Return KNsk1: push bc push de call Get_Next_Char ; Get the next character pop de pop bc jr KNlp1 KNDone: call Put_Back_Char ;Put the character back ld a,b ;(get the character counter) ld (Dict_Length),a ;Update dictionary buffer Length ld a,0 ;Set Returned Status ret ;Return page ;---------------------------------------------------------------------- ; Lookup Key Name (28_Feb_84) ;---------------------------- ; 1) This routine searches the key 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 ; HL -> Enter pointing to Start of Dictionary to search ; Lookup_Key_Name: 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,Missing_Key_Def ; Set Returned Error Status ret ; Return SrcLp1: ld (Save_Pointer),hl ;Loop Save the pointer to the arg inc hl 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,Bad_Key_Name ; 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 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 ;---------------------------------------------------------------------- ; Update Key Table (28_Feb_84) ;----------------------------- ; 1) This routine enters one byte into the Local Key Table and keeps ; track of how many entries have been made. ; 2) If the Maximum Table Size is exceeded then a Key Overflow error ; code is returned; Else, the accm is returned equal to zero. ; 3) Register Usage: ; A -> Returned 0 for OK, or Key_Overflow for Error ; DE -> Used in range checking and offset generation ; HL -> Pointer into the Local Key Table ; Update_Key_Table: ld hl,Max_Key_Length ;HL:= Maximum Length of Local Key Buffer ld de,(Key_Length) ;DE:= Offset to current position or a ;(clear carry) sbc hl,de ;If (Local Key Buffer has overflowed) jr nc,UKSk1 ld a,Key_Overflow ; Set Returned Error Status ret ; Return UKSk1: ld hl,Key_Table add hl,de ;HL:= Pointer to current location ld (hl),a ;Save char in local key table inc de ld (Key_Length),de ;(Increment the current table length) ld a,0 ;Set Returned Status OK ret ;Return page ;====================================================================== ; Get Next Line (28_Feb_84) ;========================== ; 1) This routine reads characters until it finds either a carriage ; return or an End of File Mark. ; Get_Next_Line: Call Get_Next_Char ;Loop Get a Character cp Cr ; If (Character eq End of Line) jr z,GlSk1 ; Break cp EOF ; If (Character eq End of File) jr nz,Get_Next_Line ; Break GlSk1: call Put_Back_Char ;Put last char back into record buffer ret ;---------------------------------------------------------------------- ; Get Non White (29_Feb_84) ;-------------------------- ; 1) This routine reads characters until it finds a character that ; is NOT a Space, NOT a Line Feed and NOT a Tab. ; Get_Non_White: call Get_Next_Char ;Repeat cp Space ; Get the Next Character jr z,Get_Non_White cp Tab jr z,Get_Non_White ;Until ((Char ne Space) and cp Lf ; (Char ne Tab) and jr z,Get_Non_White ; (Char ne Line Feed)) ret ;Return ;---------------------------------------------------------------------- ; Force Character to Upper Case (2_Mar_84) ;----------------------------------------- ; 1) This routine forces the character passed in the accm to ; upper case if its entry value is lower case. ; Force_Upper_Case: and 7fh ;mask off parity bit cp 'a' ;If (Char lt Lower case a) ret c ; Return cp 'z'+1 ;If (Char gt Lower case z) ret nc ; Return sub 20h ;Force Character to Upper Case ret ;Return ;---------------------------------------------------------------------- ; Put Back Character (29_Feb_84) ;------------------------------- ; Put_Back_Char: ld (Put_Back_Buf),a ;Put Back Char:= current char ret ;Return page ;---------------------------------------------------------------------- ; Get Next Character (29_Feb_84) ;------------------------------- ; 1) This routine reads the next character from the source file. ; 2) If the buffer is empty (Record_Offset ge Max_Rec_Length) then it ; is filled from the previously opened file. ; 3) Carriage Returns Cause the Line Counter to be incremented. ; Get_Next_Char: ld a,(Put_Back_Buf) ;If (a character was put back) or a jr z,GnSk1 ld c,a ; (save the character ld a,0 ld (Put_Back_Buf),a ; Put Back Char:= none ld a,c ; (restore the char) ret ; Return GnSk1: ld a,(Record_Offset) ld e,a ;E:= Current offset in record ld a,Max_Rec_Length ;A:= Maximum length of record sub e ;If (We're at the end of the record) jr nz,GnSk2 push bc ld c,Bdos_Read_Seq ; C:= Read Sequential Function # ld de,Fcb1 ; DE:= Pointer to FCB call Bdos_Entry ; Read the next record pop bc or a ; If (there was a read error) ld a,Disk_Read_Error ; Set Error Return Status ret nz ; Return ld e,0 ; Re:Initialize the E reg GnSk2: ld d,0 ld hl,Record_Buffer add hl,de ;HL:= Pointer to current character ld a,e inc a ld (Record_Offset),a ;Update Record Offset ld a,(hl) ;Return Current Character and 01111111b ;Mask off the Parity Bit cp Cr ;If (Character eq carriage return) jr nz,GnSk3 ld a,(Line_Count) inc a ld (Line_Count),a ; Increment the line count ld a,Cr ; (restore the carriage return) GnSk3: ret ;Return page ;====================================================================== ; Restore the Current Drive and User Number (27_Jul_84) ;====================================================== ; 1) This routine restores the Current User Area and Drive Number. These ; parameters were saved in the Routine Save_Param. ; Restore_Param: ld a,(Entry_User) ld e,a ;E:= Entry User Area ld c,Bdos_Get_User ;C:= Bdos Get User Number call Bdos_Entry ;Set the Current User Area to 0 ld a,(Entry_Drive) ld e,a ;E:= Entry Drive Number ld c,Bdos_SelDsk ;C:= Bdos Select Disk Function call Bdos_Entry ;Select Drive A: ret ;Return page ;====================================================================== ; Inject Function Keys (27_Jul_84) ;================================= ; Inject_Keys: ld hl,(Key_Length) inc hl ld (Key_Length),hl ;Include Number of keys byte in length call Install_Switches ;Install Switch Line Settings (Fast/Slow) call Get_the_pool ;Get the free space pool call Get_Pointers ;Get pointers in free space pool ld de,(FS_Length) ld hl,(FC_Length) add hl,de ;HL:= Free_space_len + Function_key_len ld de,(Key_Length) or a ;(clear the carry) sbc hl,de ;If (there's insufficient Free Space) jr nc,IKsk1 ld a,Table_too_Big ; Set Error Return Status ret ; Return IKsk1: ex de,hl ld hl,(FS_Pointer) dec hl dec hl ;(move DE to start of length pointer) ld (hl),e inc hl ld (hl),d ;Update the Free_Space Length inc hl add hl,de ;HL:= Current Position + Free Space len ld a,Id_IMS ld (hl),a ;Write Ims Buffer Code ld de,(IMS_Length) inc hl ld (hl),e inc hl ld (hl),d ;Write Ims Buffer Length inc hl push hl ex de,hl ;DE:= Destination (current pool pntr) ld hl,(IMS_Pointer) ;HL:= Source (current ims start) ld bc,(IMS_Length) ;BC:= Count (Length of the Ims buffer) call Move_a_Block ;Move the Ims Sting Body pop hl ld de,(IMS_Length) add hl,de ld bc,(Key_Length) ;BC:= Count (length of key table) ld a,Id_FC ld (hl),a ;Write Function Key Code inc hl ld (hl),c inc hl ld (hl),b ;Write Fuction Key Length inc hl ex de,hl ;DE:= Destination (current pool pntr) ld hl,Number_of_Keys ;HL:= Source (Start of local Table) ldir ;Move the Function Key Table call Put_the_Pool ;Restore the free space pool ld a,0 ;Set Returned Status to OK ret ;Return page ;---------------------------------------------------------------------- ; Install Switch Line Settings (27_Apr_84) ;----------------------------------------- ; Install_Switches: call Get_Version ;If (Version is CP/M 3) jr nz,IsSk1 ld a,F_Get_RamDatY ld de,Temp_Buffer ; DE:= Pointer to Local Buffer call Call_Cold_Boot ; Move System Memory into the local buffer push de ld a,(Temp_Buffer+CFlag_Offset) and Not $FunAct_Cpm3 ld e,a ; E:= CFlag with FunAct removed ld a,(Fast_Slow) ; A:= Fast_Slow Flag Value and $FunAct_Cpm3 ; Isolate the Fast_Slow bit or e ; A:= Updated value of CFlag ld (Temp_Buffer+CFlag_Offset),a pop de ld a,F_Write_Sys ; Function_1:= Write to system memory ex de,hl ; Swap Source and Destination call Call_Cold_Boot ; Write buffer back into system memory ret ; Return IsSk1: ld hl,(Bios_Entry+1) ;Else HL:= Pointer to start of Bios ld de,RamDatY_Offset add hl,de ; HL:= Pointer to Pointer to... ld e,(hl) inc hl ld d,(hl) ex de,hl ; HL:= Pointer to start RamDatY ld de,SFlag_Offset ; DE:= Offset to SFlag (negative) or a ; (clear the carry) sbc hl,de ; HL:= Pointer to SFlag ld a,(hl) ; A:= Current SFlag Value and Not $FunAct_Cpm2 ld e,a ; E:= SFlag w/Fast_Slow bit reset ld a,(Fast_Slow) ; A:= Fast_Slow Flag Value and $FunAct_Cpm2 ; Isolate the Fast_Slow bit or e ; A:= Updated value of SFLag ld (hl),a ; Update SFlag ret ; Return page ;---------------------------------------------------------------------- ; Get Pointers into the Free Space (1_Mar_84) ;-------------------------------------------- ; 1) This routine finds and records a) the Free Space Pointer, b) the ; Ims Buffer, and c) the Function Key Table starting address and ; Length ; 2) Register Usage: ; C -> holds the desired function key code ; DE -> holds length of desired data structure ; HL -> Enter pointing to the start of the free space pool. ; Get_Pointers: ld c,Id_FS call Find_a_Code ld (FS_Pointer),hl ;Save the Free Space Argument Pointer ld (FS_Length),de ; " " " " Length add hl,de ;HL:= Pointer to next entry ld c,Id_IMS call Find_a_Code ld (IMS_Pointer),hl ;Save the IMS Argument Pointer ld (IMS_Length),de ; " " " " Length add hl,de ;HL:= Pointer to next entry ld c,Id_FC call Find_a_Code ld (FC_Pointer),hl ;Save the Function Key Table Pointer ld (FC_Length),de ; " " " " " Length ret ; Find a Function Key Code ;------------------------- ; -This routine is only used by the Get_Pointers routine. ; Find_a_Code: ld a,(hl) ;Loop A:= Current function code inc hl ld e,(hl) inc hl ld d,(hl) ; DE:= Length of argument inc hl ; HL:= Pointer to Start argument cp c ; If (Current_FC eq Desired_FC) ret z ; Return add hl,de ; HL:= Pointer to next code jr Find_a_Code page ;---------------------------------------------------------------------- ; Check the CP/M version (17_Jul_84) ;----------------------------------- ; 1) This routine checks the CP/M version. It returns with the ; Z flag = 1 if CP/M 3. ; Get_Version: push bc push de push hl ld c,Bdos_Ret_Ver ;Return version Bdos call call Bdos_Entry ld a,0f0h and l cp 30h pop hl pop de pop bc ret page ;---------------------------------------------------------------------- ; Geô thå Free Space Pooì (16_Apr_84) ;----------------------------------- ; 1) This routine calls the BDOS to determine the version of CP/M. ; ; For CP/M 3, this routine forces the destination to be the local ; buffer, calls the cold start (extended bios functions) entry ; point, and then saves the registers after swapping hl and de. ; ; For CP/M 2 this routine simply returns a pointer to the pool ; in the BIOS. ; Get_the_pool: call Get_Version ;If (Version is CP/M 3) jr nz,cpm2 ld a,F_Get_Pool ld de,Pool_Copy ; DE:= Pointer to Local Buffer call Call_Cold_Boot ; Move Sys_Mem into local buffer ld (save_BC),bc ; Save the returned registers ex de,hl ; HL:= Pointer to first xlt ld (save_DE),de ld (save_HL),hl ld hl,Pool_Copy ret ; Return cpm2: ld hl,(1) ;Else warm boot adress ld de,Pool_Offset ; offset to pool pointer add hl,de ld a,(hl) ; get pool pointer inc hl ld h,(hl) ld l,a ret ; Return ;---------------------------------------------------------------------- ; Restore the Free Space Pool (16_Apr_84) ;--------------------------------------- ; 1) This is the inverse of Get_the_pool; It replaces the system's memory ; with the contents of the local buffer. ; 2) Get_the_pool MUST be called before entering this routine. ; Put_the_Pool: call Get_Version ;check the version of CP/M ret nz ;return if CP/M 2 ld a,F_Write_Sys ;Function_1:= Write to system memory ld bc,(Save_BC) ld de,(Save_DE) ld hl,(Save_HL) ;Restore the Returned Registers call Call_Cold_Boot ;Write buffer back into system memory ret page ;====================================================================== ; Inject New Command Line in Ims Buffer (6_Aug_84) ;================================================= ; Inject_Command: ld hl,Old_Input_Line ;HL:= Pointer to Old Input Line ld a,(hl) ;If (The Old Command Line Length eq 0) or a ret z ; Return ld e,a ld d,0 ex de,hl ;DE:= Pointer to Old Command Line Start add hl,de ;HL:= Pointer to End of Old Cmnd Line ld a,(hl) cp '\' ;If (Last Char eq '\') jr nz,IcSk1 ld a,(de) ; dec a ; Decrement the Line Length jr IcSk2 IcSk1: inc hl ;Else ld (hl),';' ; Terminate the Line w/Cr ld a,(de) inc a ; Increment the Line Length IcSk2: ld (de),a ;Set the Line Length call Translate_Ims ;Translate any special Ims Characters ld a,F_Inject_Ims ;A:= Inject Ims Function call Call_Cold_Boot ;Inject the Ims String ret ;Return ;---------------------------------------------------------------------- ; Translate the Characters in an Ims Buffer (5_Aug_84) ;----------------------------------------------------- ; 1) This routine translates the special characters in an Ims Buffer. ; 2) Summary of Special Ims Characters: ; ; Carriage Return ; | Carriage Return/Halt Processing Until next Warm Boot ; ^ Preceeds control characters ; \ Next character is to be taken literally ; 3) Register Usage: ; B -> Ims String Length ; C -> Counter for removed characters ; DE -> Enter equal pointing to start of Ims Buffer (Load Pointer) ; HL -> Storage Pointer into Ims String ; Translate_Ims: push de push de ;DE:= Start of Ims String pop hl ;HL:= Start of Ims String ld b,(hl) ;B:= length of String ld c,0 ;C:= Removed Character Counter:= 0 ImsLp2: inc hl ;Repeat (pointer (HL) to next character) inc de ; (pointer (DE) to next character) ld a,(de) cp ';' ; If (char eq Standard_Cr) jr nz,ImsSk2 ld a,Cr ; substitute Cr jr ImsSto ImsSk2: cp '|' ; Else If (char eq Pause_Cr) jr nz,ImsSk3 ld a,PCr ; substitute pause Cr jr ImsSto ImsSk3: cp '^' ; Else If (Char eq control) jr nz,ImsSk4 dec b ; If (Line_Length-1 eq 0) jr z,ImsOut ; Break inc c ; Increment Length_Adjustment inc de ld a,(de) and 5Fh ; Force it to upper case sub 40h ; Convert it to a control char. jr ImsSto ImsSk4: cp '\' ; Else If (char eq back slash) jr nz,ImsSto dec b ; If (Line_Length-1 eq 0) jr z,ImsOut ; Break inc c ; increment Length_Adjustment inc de ; (move inp_pointer to next char) ld a,(de) ; substitute next character jr ImsSto ImsSto: ld (hl),a ; Store the Character djnz ImsLp2 ;Until (all of buffer is processed) ImsOut: pop de ;DE:= Start of Ims String ld a,(de) ;A:= Length Byte sub c ;Subtract number of non-printing char ld (de),a ;Save the adjusted length ret page ;---------------------------------------------------------------------- ; Call the Bios Cold Boot Entry Point (4_Jan_84) ;----------------------------------------------- ; 1) The Cold Boot Entry point to the bios (1st entry in the bios ; jump table) is located by looking at locations 1 & 2 which ; point to the warm boot address (the desired address + 3). ; Call_Cold_Boot: push hl ;Save the HL Register Pair ld hl,(Bios_Entry+1) ;HL:= Warm Boot Address ld l,0 ;HL:= Cold Boot Address ex (sp),hl ;Restore the HL Register Pair ret ;Goto The Cold Boot entry page ;-------------------------------------------------------------------- ; Move_a_Block (1_Mar_84) ;------------------------ ; 1) This routine moves a block of memory. The block can overlay itself. ; 2) Register Usage: ; BC -> Byte Count ; DE -> Destination ; HL -> Source ; Move_a_Block: ld a,b ;If (Length of move is zero) or c ret z ; Return push hl or a ;(clear the carry) sbc hl,de ;If (Source eq Destination) pop hl ret z ; Return jr c,MBSk1 ;Else If (Source gt Destination) ldir ; Move the Block Up ret ; Return MBSk1: push hl ex de,hl ;Else (Source lt Destination) or a ; (clear the carry) add hl,bc ; Dest:= Dest + Byte_Count dec hl ; (move pointer back to last char) ex de,hl pop hl add hl,bc ; Source:= Source + Byte_Count dec hl ; (move pointer back to last char) lddr ; Move the Block Down ret ; Return page ;====================================================================== ; Report Errors (29_Feb_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,ErrOpn ld c,Bdos_PString call Bdos_Entry ;Print the Start of the Opening Message ld a,(Line_Count) ld l,a ld h,0 ;HL:= Line Number call Print_Line_Number ;Print the line number 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 (5_Mar_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_Line_Number: ld bc,0FFFFh push bc ;Put end flag on stack ld bc,10 ;divisor:= 10 dloop: call divide ;Repeat Divide push hl ; Save the remainder ld hl,9 or a sbc hl,de ex de,hl ; (Move quotient to dividend) jp c,dloop ;Until (quotient is less than 9) ld a,l ;Move the last result into the accm ploop: add a,'0' ;Repeat ld e,a ; Conver number to ascii ld c,2 call 5 ; Print the number pop hl ; Get the next number ld a,l cp 0FFh jr nz,ploop ;Until (end of stack flag has been read) ret ;Return page ;---------------------------------------------------------------------- ; 16 bit Divide (5_Mar_84) ;------------------------- ; this routine was written by Bill Smith. ; 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 ;hi *2 push hl ;save in case borrow or a ;clear borrow sbc hl,bc ;sbc hl,bc ;hi=hi-divisor ccf ;invert borrow for shift later jr c,divid1 ;if borrow { pop hl ;replace with original hi push hl ;stack phase divid1: inc sp inc sp ;drop ex de,hl ;get lo adc hl,hl ;lo *2 + remainder ex de,hl dec a ;count-- jr nz,divid0 ;while not done, loop ret page ;====================================================================== ; Error Code Tables and Message Strings (26_Apr_84) ;================================================== ; ;Error Message String Lookup Table ;--------------------------------- ; Error_Table: db Missing_Key_Def ;No Key Definition dw MKDmsg db Bad_Key_Name ;Missing Function Key Name dw BKNmsg db Invalid_Key ;Invalid Function Key Assignment dw IKmsg db Def_too_Long ;Key Definition String is too long dw DTLmsg db Temp_Overflow ;Temp buffer overflowed dw TOmsg db Key_Overflow ;Local Function Key Table Overflowed dw KOmsg db Table_too_Big ;Function Key Table is too large dw TTBmsg db No_Key_File ;No Key file name dw NKFmsg db Bad_Key_File ;Can't open the key file dw BKFmsg 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 Bad_Switch ;Illegal Switch Definition dw BSmsg End_Table: Max_Error equ ( (End_Table - Error_Table)/3 ) + 1 page ; Error Message Strings (26_Apr_84) ;---------------------------------- ; MKDmsg: db ' No Key Definition $' BKNmsg: db ' Missing Function Key Name $' IKmsg: db ' Invalid Function Key Assignment $' DTLmsg: db ' Key Definition String is too long $' TOmsg: db ' Temp buffer overflowed $' KOmsg: db ' Local Function Key Table Overflowed $' TTBmsg: db ' Function Key Table is too large $' NKFmsg: db ' No Key file name $' BKFmsg: db ' Unable to open the key 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 $' BSmsg: db ' Illegal Name in Switch Setting Line $' NoCode: db ' Unrecognized Error $' ErrOpn: db Cr,Lf, 'Error on line $' page ;====================================================================== ; Key Dictionary Macro Definitions (28_Feb_84) ;============================================= ; ; Generate a Function Key Dictionary Entry (28_Feb_84) ;----------------------------------------------------- ; 1) This macro generates an entry in the function key dictionary. ; 2) Each entry in the dictionary has the following form ; 1 byte Length of the name string ; 3 bytes Key definitions (normal, shifted and contol) ; n bytes Name of function key ; DfKey macro Name, K1, K2, K3 local L1, L2 db K1 ;Key Output for UnShifted db K2 ; " " " Shifted db K3 ; " " " Control 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 (30_Jul_84) ;--------------------------- ; 1) This Dictionary contains all of the Function Key Codes ; Key_Dictionary: DfKey F1, 40h, 60h, 0h DfKey F2, 41h, 61h, 1h DfKey F3, 42h, 62h, 2h DfKey F4, 43h, 63h, 3h DfKey F5, 44h, 64h, 4h DfKey F6, 45h, 65h, 5h DfKey F7, 46h, 66h, 6h DfKey F8, 47h, 67h, 7h DfKey F9, 48h, 68h, 8h DfKey F10, 50h, 52h, 53h DfKey FA, 1Ch, 7Ch, 5Ch DfKey FB, 1Dh, 7Dh, 5Dh DfKey FC, 1Eh, 7Eh, 5Eh DfKey FD, 1Fh, 7Fh, 5Fh DfKey UP, 4Ah, 6Ah, 0Ah DfKey DOWN, 4Bh, 6Bh, 0Bh DfKey LEFT, 4Ch, 6Ch, 0Ch DfKey RIGHT, 4Dh, 6Dh, 0Dh DfKey ERASE, 49h, 69h, 9h DfKey HOME, 4Eh, 6Eh, 0Eh DfKey HELP, 4Fh, 6Fh, 0Fh DfKey TAB, Null, 1Ah, 1Bh DfKey 0, 30h, 20h, 10h DfKey 1, 31h, 21h, 11h DfKey 2, 32h, 22h, 12h DfKey 3, 33h, 23h, 13h DfKey 4, 34h, 24h, 14h DfKey 5, 35h, 25h, 15h DfKey 6, 36h, 26h, 16h DfKey 7, 37h, 27h, 17h DfKey 8, 38h, 28h, 18h DfKey 9, 39h, 29h, 19h DfKey <.>, 2Ah, 2Bh, 2Ch DfKey ENTER, 2Dh, 2Eh, 2Fh DfKey <->, 3Ah, 3Bh, 3Ch DfKey <,>, 3Dh, 3Eh, 3Fh DfEnd ;End of the table ;---------------------------------------------------------------------- ; Non_Printing Key Dictionary (26_Apr_84) ;---------------------------------------- ; 1) This Dictionary contains all of the Special Key names for non- ; printing keys. These names only can appear on the right side of ; the definition. ; Non_Dictionary: DfKey _TAB, 9, 0, 0 ;Tab DfKey _ESC, 1Bh, 0, 0 ;Escape DfKey _DEL, 7Fh, 0, 0 ;Delete DfKey _RTN, 0Dh, 0, 0 ;Carriage Return DfKey _SLW, Slow, 0, 0 ;Slow - Return Char In Status False DfKey _FST, Fast, 0, 0 ;Fast - Return Char In Status True DfEnd ;End of the table page ;====================================================================== ; General Data Area (3_Aug_84) ;============================= ; 1) Note that the Key_Length during the run time of the translator ; is always equal to the function key table length - 1. The - 1 ; condition is forced because the Number_of_Keys byte is not included. ; ;Key.com Revision Number Key_Rev_Msg: db Cr,Lf,'Key.com Revision ' db ((rev and 0F0h) shr 4) + '0', '.', (rev and 0Fh) + '0' db Cr,Lf,'$' ;File Handeling Variables Default_Ext: db 'KEY' Entry_User: db 0 ;Active User Area on entry to this program Entry_Drive: db 0 ;Active Drive on entry to this program ;Local Variables Save_Pointer: dw 0 ;Temp pntr storage (Lookup_Key_Name) Line_Count: db 0 ;Current Line Count (Get_Next_Char) Put_Back_Buf: db 0 ;Character put back (Put_Back_Char) Fast_Slow: db 0 ;Ims Buffer response to console status when active ;Free Space Pointers and Lengths FS_Pointer: dw 0 ;Free space pointer FS_Length: dw 0 ; " " length IMS_Pointer: dw 0 ;Ims pointer IMS_Length: dw 0 ; " length FC_Pointer: dw 0 ;Function Key Table pointer FC_Length: dw 0 ; " " " length ;Register Storage (for get and put pool functions) Save_BC: dw 0 ;Save Location for the BC register pair Save_DE: dw 0 ; " " " " DE " " Save_HL: dw 0 ; " " " " HL " " ;Temporary Buffers Temp_Length: db 0 ;Current Length of the Temp Buffer Temp_Buffer: ds Max_Temp_Length ;Temporary Buffer (init to spaces) Chain_Command: ds 10h,' ' ;Chain Command Buffer Old_Input_Line: db 0 ;Length of Old Input Command Line ds 80h,' ' ;Text of Old Input Command Line ;Dictionary Buffer Dict_Length: db 0 ;Length of Dictionary Buffer Dict_Buffer: ds Max_Dict_Length ;Dictionary buffer (see Lookup_Dict) ;Local Copy of Key Table Key_Length: dw 0 ;Offset into the Function Key Table Number_of_Keys: db 0 ;Number of function key definitions Key_Table: ds Max_Key_Length ;Local Function Key Table ;Source Buffer Record_Offset: db Max_Rec_Length ;Current Record Position (init end rec) Record_Buffer: ds Max_Rec_Length ;Current Record from disk Pool_Copy: ds Max_Pool_Length ;Copy of the free space pool ds Max_Stack_Space ;Main Stack Main_Stack: end