Title Program Loader for the MD-11 using CP/M 3 (3_Aug_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 combined with one of the 'list' files ; (eg hdlm5.mac) at link time (ie l80 hdl,hdlm5,hdl/n/e) ; Index: (31_Jul_84) ;------------------- ; ; Main 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 ; PutIMS Put the Ims string into the IMS buffer ; Get_Pointer Return a Pointer to the Desired Entry ; Get_Response Get the User's Response ; Get_Buffer Move system memory into the local buffer ; Put_Buffer Put the Local Buffer into System Memory ; Do_Cold 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 ;------------------- 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 PutIMS) Esc equ 1Bh ;Escape Bright equ '(' ;Start High Lighting Dim equ ')' ;Start Low Lighting page ;---------------------------------------------------------------------- ; 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 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 the user wants to stop) jr nz,MDone ; Quit call PutIms ;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 Do_Cold ;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) ;------------------------------ le 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,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,Fcb call Bdos_Entry ; Find the Key File On the --------------------------------- ; 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,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 Do_Cold ;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) Point he 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 Respo ----------------------------------------- ; 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. ; Get_Buffer: ld de,Local_Buffer ;DE:= Pointer to Local Buffer call Do_Cold ;Move System Memory into the 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 ret ;Return ;---------------------------------------------------------------------- ; Put the Local Buffer into System Memory (4_Jan_84) ;--------------------------------------------------- ; 1) This is the inverse of Get_Buffer; It replaces the system's memory ; with the contents of the local buffer. ; 2) Get_Buffer is usually called before entering this routine to set up ; the Save_?? locations). ; Put_Buffer: ld a,1 ;Function_1:= Write to system memory ld bc,(Save_BC) ld de,(Save_DE) ld hl,(Save_HL) ;Restore the Returned Registers call Do_Cold ;Write the Mtabs back into system memory ret ;---------------------------------------------------------------------- ; Do_Cold - 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). ; Do_Cold: 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 ;--------------------------------------------------------------------- orrow 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 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) ;------------------------------ ; Fcb: ds 32,0 Save_BC: dw 0 ;Save Location for the BC register pair Save_DE: dw 0 ; " " " " DE " " Save_HL: dw 0 ; " " " " HL " " Local_Buffer: ds 128,0 end