Title Program Loader for the MD-11 using CP/M 3 (10_Sept_84) ; ; Copyright 1984 ; Morrow Designs, Inc ; San Leandro, Ca. .z80 aseg org 0100h ; This program allows you to batch command strings to the ; Ims facility. Additionally, you have the option to check for the ; existance of a file before the ims string is submitted which allows ; you to do validity checks. ; The actual commands strings, prompt strings and the list of ; files to be loaded are coded as include files selected by the first ; block of equates in the Equates section. ; There are two major data structures that are used to drive this ; program. The first is a parameter block kept in page zero while the ; program is running. It consists of an ID word followed by the current ; iteration (0 to n) followed by the maximum number of iterations. ; The second data structure is a list of Key_File/Prompt_Strings ; and Ims_Buffer pairs called LodLst. This list is indexed by the ; variable 'LodOff'. ; Note: This file must be combined with one of the 'list' files ; (eg hdlm5.mac) at link time (ie l80 hdl,hdlm5,hdl/n/e) ; Index: (10_Sept_84) ;-------------------- ; ; Main_Line Main Line ; Check_Ccl Check the Cbios Compatibility Level ; Clear_Screen Clear the Console Screen ; Look_for_File Check for the existance of the key file ; Install_Ims Put the Ims string into the IMS buffer ; Get_Pointer Return a Pointer to the Desired Entry ; Get_Response Get the User's Response ; Extended_Bios Call the Bios Cold Boot Entry Point ; -- General Parameters ; -- Program Load List ; -- Prompt Strings ; -- Error Messages page 64 ;---------------------------------------------------------------------- ; External Definitions (3_Aug_84) ;-------------------------------- ; 1) This variables are defined in the 'List' files (eg hdlm16.mac) ; External LodLst External LodLen ;---------------------------------------------------------------------- ; Equates (3_Aug_84) ;------------------ ; True equ 0FFFFh False equ 0 Null equ 0FFh ;Null Key filespec prompt ; IDs and Rev Numbers ;-------------------- ; CpmVer equ 30h ;Cpm Version Number Ccl equ 1 ;Cbios Compatibility Level Prev equ 11h ;Program revision number PID equ 'Ok' ;Program ID ; Address Definitions ;-------------------- ; Bios_Entry equ 0 ;Address of the Start of the BIOS + 3 Bdos_Entry equ 05h ;Address of the start of the BDOS IBuf equ 80h ;tail buffer location PIDadd equ 40h ;Address of the ID word LodOff equ PIDadd + 2 ;Current Program Load offset LodMax equ PIDadd + 3 ;Maximum number of load files ErrFlag equ PIDadd + 4 ;Error Flag ; Bdos Function Numbers ;---------------------- ; Bdos_ConOut equ 2 ;Console Output a Character Bdos_DirIO equ 6 ;Direct console control Bdos_PString equ 9 ;Print a string Bdos_GetRev equ 0Ch ;Get the revision number of this cpm system Bdos_SFirst equ 11h ;Search for the first occurance of file x Bdos_SetDMA equ 1Ah ;Set the DMA Address Bdos_SetEM equ 2Dh ;Set the Bdos error return mode InWait equ 0FDh ;Direct console input (waits until char ready) InjIMS equ 11 ;Extended Function - Inject IMS String ; Offsets ;-------- ; Ccl_Offset equ 10 ;Offset to Clevel from start of char. struct. Key_Offset equ 0 ;Key File Offset Ims_Offset equ 2 ;Ims Sting Offset ; Non Printing Ascii Character Equates ;------------------------------------- ; CntrlC equ 3 ;Control C Code (Warm Boot) Bell equ 7 ;Bell Code Tab equ 9 ;Tab Lf equ 0Ah ;Line Feed Cr equ 0Dh ;Carriage Return PCr equ 8Dh ;Pause carriage return (see Install_Ims) Esc equ 1Bh ;Escape Bright equ '(' ;Start High Lighting Dim equ ')' ;Start Low Lighting page ;---------------------------------------------------------------------- ; Main Line (14_Feb_84) ;---------------------- ; Main_Line: ld hl,(PIDadd) ;HL:= Contents of the ID word location ld de,PID ;DE:= Program ID word or a ;(Clear carry) sbc hl,de ;If (ID hasn't been written) jr z,MSkp1 call Check_Ccl ; Check CP/M rev/compatibility level or a ; If (Rev levels aren't high enough) jr nz,Mdone ; Quit call Clear_Screen ; Clear the Console Screen ld de,Prmpt1 ld c,Bdos_PString call Bdos_Entry ; Print the initial prompt ; call Get_Response ; Get the user response ; or a ; If (Response eq Stop) ; jr nz,MDone ; Quit ld de,PID ld (PIDadd),de ; Write the ID ld a,0 ld (LodOff),a ; Reset the Load Offset ld (ErrFlag),a ; Reset the Error flag ld a,(LodLen) ld (LodMax),a ; Set the Maximum number of load files MSkp1: ld a,(ErrFlag) ;see if previous copy O.K. or a jr z,CopyOk ld a,(LodOff) ;decrement Load Offset if Error dec a ld (LodOff),a CopyOk: ld c,Bdos_SetEM ;C:= Bdos Set Error Mode (funct 45) ld e,0FEh ;E:= Return and Display Mode call Bdos_Entry ;Set the Error Return Mode call Look_for_File ;Get the user to load the next disk or a ;If (the user wants to stop) jr nz,MDone ; Quit call Install_Ims ;Install the Ims String or a ;If (There wasn't room for Ims String) jp nz,MDone ; Quit ld a,(LodOff) inc a ld (LodOff),a ;Load Offset:= Load Offset + 1 ld b,a ld a,(LodMax) ;(A:= Last Load File Number) cp b ;If (this is the last file) jr nz,MSkp4 MDone: ld de,0 ld (PIDadd),de ; Reset the ID word MSkp4: ld a,1 ;set flag ld (ErrFlag),a jp Bios_Entry ;Goto the Bios Warm Boot Entry page ;---------------------------------------------------------------------- ; Check the Cbios Compatibility Level (20_Jul_84) ;------------------------------------------------ ; Check_Ccl: ld c,Bdos_GetRev ;C:= Bdos get cpm version number call Bdos_Entry ;Get version number in L ld a,l ;A:= Cpm Version 14, 22 or 31 and 0F0h ;Mask off the minor revision number cp CpmVer ;If (version doesn't match expected version) jr nz,CclErr ; Goto Error return ;Check the Cbios Compatibility Level ld a,6 ;A:= Function_6 (Return Character table) ld de,Local_Buffer ;DE:= Pointer to the local buffer call Extended_Bios ;Move Character table into local buffer ld hl,Ccl_Offset ;HL:= offset to Cbios compatiblity level add hl,de ;HL:= Pointer to Cbios compatibility level ld a,Ccl cp (hl) ;If (compatibility level le Cbios Ccl) jp c,CclErr Cclok: ld a,0 ; A:= Return Status = Ok ret ; Return CclErr: ld de,Err1 ;DE:= revision error message ld c,Bdos_PString ;C:= Print string function number call Bdos_Entry ;Print the Input Drive number string ld a,0FFh ;A:= error return status ret ;Return page ;---------------------------------------------------------------------- ; Clear the Console Screen (20_Jul_84) ;------------------------------------- ; 1) This Routine Simply outputs a Carriage Return followed by 50 Line ; Feeds to the Console. ; 2) NONE of the Register Pairs are altered. ; Clear_Screen: push bc push de push hl ld c,Bdos_ConOut ;C:= Bdos Console Output Function Number ld e,Cr ;E:= Carriage Return call Bdos_Entry ;Print a Carriage Return ld b,50 ;B:= Character Counter ld c,Bdos_ConOut ;C:= Bdos Console Output Function Number CsSk1: push bc ;Repeat ld e,Lf ; E:= Line Feed call Bdos_Entry ; Print the Line Feed pop bc djnz CsSk1 ;Until (Character Counter - 1 eq 0) pop hl pop de pop bc ret ;Return page ;---------------------------------------------------------------------- ; Prompt for Key file then Check search for it (7_Feb_84) ;-------------------------------------------------------- ; 1) This routine checks for the existance of a particular file on ; a particular disk. ; 2) If the File Name String is Null (0) then the file check is ; NOT preformed. ; Look_for_File: ld bc,Key_Offset ;Loop BC:= Offset to the Prompt string call Get_Pointer ; HL:= Pointer to base of Prompt string table ld a,(hl) ; If (The File Name string is Null) cp Null ld a,0 ret z ; Return (No Error) inc hl ; HL:= Source (Start of FCB) ld de,Local_Fcb ; DE:= Destination (Local FCB) ld bc,13 ; BC:= Length of Transfer ldir ; Transfer the FCB for the Key File push hl ; (save pointer to prompt string start) ld de,Prmpt2 ld c,Bdos_PString call Bdos_Entry ; Print 'please insert the diskette... pop de ; DE:= Pointer to prompt string start ld c,Bdos_PString call Bdos_Entry ; Print title of diskette ld de,Prmpt3 ld c,Bdos_PString call Bdos_Entry ; Print remainder of prompt call Get_Response ; Get response from console (Continue/Stop) or a ; If (response eq Stop) ret nz ; Return ld c,Bdos_SetDMA ld de,Local_Buffer call Bdos_Entry ; Set the DMA Address ld c,Bdos_SFirst ld de,Local_Fcb call Bdos_Entry ; Find the Key File On the Selected Drive cp 0FFh ; If (the key file was found) ld a,0 ret nz ; Return (NO Error) ld de,Err2 ld c,Bdos_PString call Bdos_Entry ; Print Error Message jr Look_for_File page ;---------------------------------------------------------------------- ; Put the Ims string into the IMS buffer (5_Feb_84) ;-------------------------------------------------- ; 1) This routine puts the current iteration's ims string into the ; ims buffer. ; Install_Ims: ld bc,Ims_Offset ;BC:= Offset to IMS sting call Get_Pointer ;HL:= Pointer to the ims string push hl ;(save pointer on stack) ;Translate special characters in the Ims String ImsLp2: inc hl ;Repeat (move HL past the length byte) ld a,';' ; If (char eq Standard_Cr) cp (hl) jr nz,ImsSk2 ld (hl),Cr ; substitute Cr jr ImsSk3 ImsSk2: ld a,'|' ; Else If (char eq Pause_Cr) cp (hl) jr nz,ImsSk3 ld (hl),PCr ; substitute pause Cr ImsSk3: djnz ImsLp2 ;Until (all of buffer is processed) pop de ;DE:= pointer to start of processed buffer ;Inject the Ims string into the Ims buffer ld a,InjIMS ;A:= extended function call: inject ims call Extended_Bios ;do extended function ld a,0 ;If (the ims string was accepted) ret nc ; Return (no error) ld de,Err3 ;Else ld c,Bdos_PString call Bdos_Entry ; Print error (ims string won't fit) ld a,0FFh ret ; Return (ERROR) page ;---------------------------------------------------------------------- ; Return a Pointer to the Desired Entry (5_Feb_84) ;------------------------------------------------- ; 1) This routine uses the LodOff Value along with the Entry offset ; (passed in the BC pair) to form a pointer into the Load List. ; 2) The Load List is a two dimensional (n by 2 word) array. The First ; dimension of the array is the set by the current iteration number ; of the Loader Program (LodOff). The second dimension of the array ; allows access to the current Key file (and it prompt string) and ; the Ims Stings pointers. ; 3) Pointer offsets (passed in the BC pair): ; 0 = Key File Name ; 2 = Ims String Text ; 4) Register Usage: ; A -> General Purpose ; BC -> Pointer Offset or second dimension (0=Prompt,2=Key,4=Ims) ; DE -> used as Offset in calculating the first dimension ; HL -> Pointer to Desired Entry's Pointer ; Get_Pointer: ld a,(LodOff) sla a sla a ld e,a ld d,0 ;DE:= Offset - LodOff * 4 ld hl,LodLst ;HL:= Base of Load List add hl,de ;HL:= Pointer to Base of First Dimenstion add hl,bc ;HL:= Pointer to Second Dimension ld e,(hl) inc hl ld d,(hl) ;(retrieve the pointer from the table) ex de,hl ;HL:= Pointer to base of desired string ret ;Return page ;---------------------------------------------------------------------- ; Get the User's Response (7_Feb_84) ;----------------------------------- ; 1) This routine prints a prompt string and then waits for a valid ; response from the console device. ; 2) A valid response is a C (or c) for continue and S (or s) or ; control_C for stop. ; 3) Register Usage: ; AF -> Returned 0 for continue or 0FFh for Stop ; BC -> Bdos function number in the C register ; DE -> On Entry Points to the string to print ; Get_Response: ld de,Prmpt4 ld c,Bdos_PString call Bdos_Entry ;print the response prompt AskLpº lä c,Bdos_DirIO ;Loop ld e,InWait ; (Set funct to wait for input) call Bdos_Entry ; Get a character from the console and 5Fh ; (force to upper case) cp 'C' ; If (Response eq Continue) jr nz,AskSk1 ld e,a ; (Save the character for echo) ld a,0 ; (Continue code) jr AskSk3 ; Return (Continue) AskSk1: cp 'S' ; Else If (Response eq Stop) jr nz,AskSk2 ; Break ld e,a ; (Save the character for echo) ld a,0FFh ; (Stop code) jr AskSk3 AskSk2: cp CntrlC ; Else IF (Response eq Control_C) jr z,AskSk4 ; Break jr AskLp AskSk3: push af ;Print the Final Carriage Return Line Feed ld c,Bdos_ConOut ;C:= Console Output Funct (char in E already) call Bdos_Entry ;Print the Response AskSk4: ld de,CrLf ld c,Bdos_PString call Bdos_Entry pop af ret ;Return 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). ; Extended_Bios: 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 ;---------------------------------------------------------------------- ; Prompt Strings (6_Nov_84) ;-------------------------- ; Prmpt1: db Esc,Bright,'MD-HD Master Disk Program Loader Rev ' db ((PRev and 0F0h) shr 4) + '0', '.', (PRev and 0Fh) + '0' db Tab,Tab,Tab,' Copyright 1984' db cr,lf,'Morrow Designs, Inc.' db Tab,Tab,Tab,Tab,Tab,Tab,'San Leandro, Ca' db cr,lf, cr,lf, cr,lf, cr,lf db cr,lf,' CP/M Master Distribution Disk' db cr,lf db cr,lf db cr,lf db cr,lf,'$' Prmpt2: db Esc, Dim, cr,lf db 'Please insert the diskette labeled:' db Esc, Bright, cr,lf,'$' Prmpt3: db Esc, Dim, cr,lf db 'into your floppy disk drive. $' Prmpt4: db Esc, Dim, Bell, cr,lf, cr,lf, 'Press ' db Esc, Bright,'C' db Esc, Dim, ' to continue or ' db Esc, Bright,'S' db Esc, Dim, ' to Stop: ' db Esc, Bright, '$' CrLf: db cr,lf,'$' page ;---------------------------------------------------------------------- ; Error Messages (5_Feb_84) ;-------------------------- ; Err1: db cr,lf,'Wrong Version of Cbios' db cr,lf,'This version of HDL Requires CP/M vers 3.0 Cbios rev ' db ccl shr 4 + 30h,'$' Err2: db cr,lf,'ERROR: This is NOT the proper disk$' Err3: db cr,lf,'ERROR: There is insufficient space in the ims buffer$' page ;---------------------------------------------------------------------- ; General Parameters (5_Feb_84) ;------------------------------ ; Local_Fcb: ds 32,0 Local_Buffer: ds 128,0 end