Title Program Loader for the MD-11 using CP/M 3 (14_Feb_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. ; 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 two dimensional array. The first ; dimension is set by the iteration counter. ; Index: (14_Feb_84) ;------------------- ; ; Main - Main Line ; CclChk - Check the Cbios Compatibility Level ; GetDsk - Check for the existance of the key file ; PutIMS - Put the Ims string into the IMS buffer ; GetBas - Return a Pointer to the Desired Entry ; GetRsp - Get the User's Response ; GetBuf - Move system memory into the local buffer ; PutBuf - Put the Local Buffer into System Memory ; DoCold - Call the Bios Cold Boot Entry Point ; -- - General Parameters ; -- - Program Load List ; -- - Prompt Strings ; -- - Error Messages page 64 ;---------------------------------------------------------------------- ; Equates (10_Feb_84) ;------------------- ; ; IDs and Rev Numbers ;-------------------- ; CpmVer equ 30h ;Cpm Version Number ccl equ 0 ;Cbios Compatibility Level Prev equ 11h ;Program revision number PID equ 'Ok' ;Program ID ; Drive Designations for Key filespec prompt strings ;--------------------------------------------------- ; X_Drive equ 0 ;Current Drive A_Drive equ 1 ;Drive A: B_Drive equ 2 ;Drive B: C_Drive equ 3 ;Drive C: Null equ 0FFh ;Null Key filespec prompt ; Address Definitions ;-------------------- ; Wboot equ 0 ;Address of the Start of the BIOS + 3 warmbt equ 01h ;Address of the Bios Warm boot entry bdos 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 42h ;Current Program Load offset LodMax equ 43h ;Maximum number of load files ErrFlag equ 44h ;Error Flag ; Bdos Function Numbers ;---------------------- ; ConIn equ 1 ;Console Input a Character ConOut equ 2 ;Console Output a Character DirIO equ 6 ;Direct console control Print equ 9 ;Print a string GetRev equ 0Ch ;Get the revision number of this cpm system SFirst equ 11h ;Search for the first occurance of file x Delete equ 13h ;Delete a file(s) SetDMA equ 1Ah ;Set the DMA Address 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 ;-------- ; CclOff equ 7 ;Offset to Clevel from start of char. struct. KeyOff equ 0 ;Key File Offset ImsOff 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 PutIMS) ClrScr equ 1Ah ;Clear Screen Esc equ 1Bh ;Escape Bright equ '(' ;Start High Lighting Dim equ ')' ;Start Low Lighting page ;---------------------------------------------------------------------- ; MAIN - Main Line (14_Feb_84) ;----------------------------- ; Main: 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 CclChk ; Check CP/M rev and compatibility level or a ; If (Rev levels aren't high enough) jr nz,Mdone ; Quit ld de,Prmpt1 ld c,Print call Bdos ; Print the initial prompt call GetRsp ; 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,SetEM ;C:= Bdos Set Error Mode (funct 45) ld e,0FEh ;E:= Return and Display Mode call Bdos ;Set the Error Return Mode call GetDsk ;Get the user to load the next disk or a ;If (the user wants to stop) jr nz,MDone ; Quit call PutIms ;Install the Ims String or a ;If (There wasn't room for the 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 Wboot ;Goto the Bios Warm Boot Entry page ;---------------------------------------------------------------------- ; CCLCHK - Check the Cbios Compatibility Level (4_Jan_84) ;-------------------------------------------------------- ; ;Check the Cpm Version Number CclChk: ld c,GetRev ;C:= Bdos get cpm version number call Bdos ;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,LocBuf ;DE:= Pointer to the local buffer call DoCold ;Move the character table into the local buffer ld hl,CclOff ;HL:= offset to Cbios compatiblity level add hl,de ;HL:= Pointer to Cbios compatibility level ld a,(hl) ;If (current compatibility levle ne Cbios Ccl) cp Ccl jp nz,CclErr ; Goto Error return Cclok: ld a,0 ;A:= Successful Completion return status ret ;Return CclErr: ld de,Err1 ; DE:= revision error message ld c,Print ; C:= Print string function number call Bdos ; Print the Input Drive number string ld a,0FFh ; A:= error return status ret page ;---------------------------------------------------------------------- ; GETDSK - 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. ; GetDsk: ld bc,KeyOff ;Loop BC:= Offset to the Prompt string call GetBas ; 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,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,Print call Bdos ; Print 'please insert the diskette... pop de ; DE:= Pointer to prompt string start ld c,Print call Bdos ; Print title of diskette ld de,Prmpt3 ld c,Print call Bdos ; Print remainder of prompt call GetRsp ; Get response from console (Continue/Stop) or a ; If (response eq Stop) ret nz ; Return ld c,setdma ld de,LocBuf call bdos ; Set the DMA Address ld c,SFirst ld de,Fcb call Bdos ; 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,Print call Bdos ; Print Error Message jr GetDsk page ;---------------------------------------------------------------------- ; PUTIMS - 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. ; PutIMS: ld bc,ImsOff ;BC:= Offset to IMS sting call GetBas ;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 DoCold ;do extended function ld a,0 ;If (the ims string was accepted) ret nc ; Return (no error) ld de,Err3 ;Else ld c,Print call Bdos ; Print error (ims string won't fit) ld a,0FFh ret ; Return (ERROR) page ;---------------------------------------------------------------------- ; GETBAS - 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 ; GetBas: 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 ;---------------------------------------------------------------------- ; GETRSP - 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 ; GetRsp: ld de,Prmpt4 ld c,Print call bdos ;print the response prompt AskLpº lä c,DirIO ;Loop ld e,InWait ; (Set funct to wait for input) call Bdos ; 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,ConOut ;C:= Console Output Funct (char in E already) call Bdos ;Print the Response AskSk4: ld de,CrLf ld c,Print call Bdos pop af ret ;Return page ;---------------------------------------------------------------------- ; GETBUF - Move system memory into the local buffer (4_Jan_84) ;------------------------------------------------------------- ; 1) 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. ; GetBuf: ld de,LocBuf ;DE:= Pointer to Local Buffer call DoCold ;Move System Memory into the local buffer ld (saveBC),bc ;Save the returned registers ex de,hl ;HL:= Pointer to first xlt ld (saveDE),de ld (saveHL),hl ret ;Return ;---------------------------------------------------------------------- ; PUTBUF - Put the Local Buffer into System Memory (4_Jan_84) ;------------------------------------------------------------ ; 1) This is the inverse of GetBuf; It replaces the system's memory ; with the contents of the local buffer. ; 2) GetBuf MUST be called before entering this routine. ; PutBuf: ld a,1 ;Function_1:= Write to system memory ld bc,(SaveBC) ld de,(SaveDE) ld hl,(SaveHL) ;Restore the Returned Registers call DoCold ;Write the Mtabs back into system memory ret ;---------------------------------------------------------------------- ; DOCOLD - 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). ; DoCold: push hl ;Save the HL Register Pair ld hl,(Wboot+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 ;---------------------------------------------------------------------- ; Program Load List (14_Feb_84) ;------------------------------ ; LodLen: db (LodEnd - LodLst)/4 LodLst: dw Key1, Ims1 dw Key2, Ims2 dw Key3, Ims3 dw Key4, Ims4 dw Key5, Ims5 dw Key6, Ims6 dw Key7, Ims7 dw Key8, Ims8 dw Key9, Ims9 dw Key10, Ims10 LodEnd: page ; Key file Names and Prompt Strings (14_Feb_84) ;---------------------------------------------- ; 1) Entry Format: ; -FCB filespec for validation file followed by a prompt string. ; -or a Null (0FFh) for No File Check ; Key1: db Null Key2: db Null Key3: db Null Key4: db NOT Null db B_Drive,'HELP HLP',0 db 'CP/M 3 Distribution Diskette Master II$' Key5: db NOT Null db B_Drive,'CORRECT COM',0 db 'Software Distribution Diskette - 1 (Correct-It)$' Key6: db NOT Null db B_Drive,'MBASIC COM',0 db 'Software Distribution Diskette - 2 (MBasic)$' Key7: db NOT Null db B_Drive,'LC COM',0 db 'Software Distribution Diskette - 3 (LogiCalc)$' Key8: db NOT Null db B_Drive,'PEARLED COM',0 db 'Personal Pearl Distribution Diskette (Disk 1 of 2)$' Key9: db NOT Null db B_Drive,'PSORT COM',0 db 'Personal Pearl Distribution Diskette (Disk 2 of 2)$' Key10: db NOT Null db B_Drive,'NWU COM',0 db 'New Word Distribution Diskette$' page ; Ims Strings (14_Feb_84) ;------------------------ ; Entry Format: ; -Valid Ims Sting in the same format as the IMS command ; carriage return = ; ; warm boot pause = | ; Ims1: db (Ims2 - Ims1) - 1 db 'format b;CONTINUE|' db 'copysys sysldr.com b:;n;' db 'hdlpip;;' db 'hdl;' Ims2: db (Ims3 - Ims2) - 1 db 'hdlpip b:=*.*;' db 'hdl;' Ims3: db (Ims4 - Ims3) - 1 db 'hdlpip;;' db 'ren b:profile.sub=b:prof1.sub;' db 'hdboot;' Ims4: db (Ims5 - Ims4) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims5: db (Ims6 - Ims5) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims6: db (Ims7 - Ims6) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims7: db (Ims8 - Ims7) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims8: db (Ims9 - Ims8) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims9: db (Ims10 - Ims9) - 1 db 'hdlpip A:=B:*.*;' db 'hdl;' Ims10: db (ImsN - Ims10) - 1 db 'hdlpip A:=B:*.*;' db 'era profile.sub;' db 'ren profile.sub=prof2.sub;' db 'pilot init;' ImsN: page ;---------------------------------------------------------------------- ; Prompt Strings (14_Feb_84) ;--------------------------- ; Prmpt1: db ClrScr,Esc,Bright,'MD-11 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,' ******* CAUTION ********' db cr,lf db cr,lf,tab,'This Program automatically formats your hard disk and then' db cr,lf,tab,'reloads it with the original distribution programs. This means' db cr,lf,tab,'that all of the data currently existing on your hard disk will' db cr,lf,tab,'be ERASED. If you have already stored data on the hard disk' db cr,lf,tab,'then you may wish to stop now and back up that data.' 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 Foreign 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) ;------------------------------ ; Fcb: ds 32,0 SaveBC: dw 0 ;Save Location for the BC register pair SaveDE: dw 0 ; " " " " DE " " SaveHL: dw 0 ; " " " " HL " " LocBuf: ds 128,0 end