1; 2; exec: function to chain to another C-generated com file, with 3; text argument passing. 4; 5; Calling sequence: 6; exec(prog, args); 7; char *prog, *args; 8; 9; where 10; prog is the name of the program being executed next 11; args is a pointer to a string of arguments separated by 12; blanks or tabs. Embedded blanks within the arguments are 13; not allowed, unless the called program does not use the 14; default FCB parameters (and most don't) and can parse the 15; command line parameter list itself (like C80 programs can). 16; 17 18 19 SECTION code_clib 20 21 PUBLIC execl 22 PUBLIC _execl 23 24 25 EXTERN _parsefcb 26 EXTERN asm_toupper 27 EXTERN l_gint 28 29 30; 31; CP/M memory pointers 32; 33DEFC __BASE = 0000H ;either 0 or 4200h for CP/M systems 34DEFC __FCB = __BASE+5CH ;default file control block 35DEFC __TBUFF = __BASE+80H ;sector buffer 36DEFC __BDOS = __BASE+5 ;bdos entry point 37DEFC __TPA = __BASE+100H ;transient program area 38DEFC __ERRV = 255 ;error value returned by bdos calls 39 40; 41; CP/M BDOS CALL MNEMONICS 42; 43DEFC __OPENC = 15 ;open a file 44DEFC __READS = 20 ;read a sector (sequential) 45DEFC __SDMA = 26 ;set dma 46 47 48execl: 49_execl: 50 51 LD HL,4 52 ADD HL,SP 53 LD E,(HL) 54 INC HL 55 LD D,(HL) ;DE points to program name now 56 57 LD HL,-60 58 ADD HL,SP ; compute &newfcb for use here 59 PUSH HL ; save for much later (will pop into bc) 60 PUSH HL ;make a few copies for local use below 61 PUSH HL 62 63 ; CP/M name->FCB routine. Call with file name address in DE, FCB IN HL. 64 ;CALL x?fcb ;set up com file for exec-ing 65 ;push hl 66 push de 67 call _parsefcb 68 pop de 69 ;pop hl 70 71 POP HL ;get new fcb addr 72 LD BC,9 ;set extension to com 73 ADD HL,BC 74 LD (HL),'C' 75 INC HL 76 LD (HL),'O' 77 INC HL 78 LD (HL),'M' 79 POP DE ;get new fcb addr again 80 LD C,__OPENC ;open the file for reading 81 CALL __BDOS 82 CP __ERRV 83 JP NZ,__NOERR 84 POP HL ;if can't (like it doesn't exist), return -1 85 LD HL,-1 86 RET 87 88 89__NOERR: 90 LD HL,4 ;get args pointer 91 ADD HL,SP 92 CALL l_gint ; CALL h. ;HL = *HL 93 CALL __SPARG ;separate them into individual strings 94 LD HL,(__ARG1) 95 LD A,H 96 OR L 97 JP NZ,__EXCL0 98 LD DE,__ARG1 ;no arguments -- create a blank FCB 99 PUSH DE ;call x?fcb with null string 100 LD HL,__FCB 101 102 ; CP/M name->FCB routine. Call with file name address in DE, FCB IN HL. 103 ;CALL x?fcb 104 105 push hl 106 push de 107 call _parsefcb 108 pop de 109 pop hl 110 111 POP HL 112 JP __EXCL6 113 114 115__EXCL0: 116 EX DE,HL 117 LD HL,__FCB 118 119 ; CP/M name->FCB routine. Call with file name address in DE, FCB IN HL. 120 ;CALL x?fcb ;stick first param into default FCB slot 121 122 push hl 123 push de 124 call _parsefcb 125 pop de 126 pop hl 127 128 LD HL,(__ARG2) ;and stick second param string 129 LD A,H 130 OR L 131 JP NZ,__EXCL6 132 LD HL,__ARG2 133 134__EXCL6: 135 EX DE,HL ;into second default fcb slot 136 LD HL,__FCB+16 137 138 ; CP/M name->FCB routine. Call with file name address in DE, FCB IN HL. 139 ;CALL x?fcb 140 push hl 141 push de 142 call _parsefcb 143 pop de 144 pop hl 145 146 LD DE,__TBUFF+1 ;now construct command line: 147 LD HL,4 148 ADD HL,SP ;HL points to arg string pointer 149 CALL l_gint ; CALL h. ;HL points to arg string 150 LD B,0 ;char count for com. line buf. 151 LD A,H ;are there any arguments? 152 OR L 153 JP Z,__EXCL9 154 OR (HL) ; (Bug fix 7/83 WB) 155 JP NZ,__EXCL5 156__EXCL9: 157 LD (DE),A ;no--zero TBUFF and TBUFF+1 158 JP __EXCL2 159__EXCL5: 160 LD A,' ' ;yes--start buffer off with a ' ' 161 LD (DE),A 162 INC DE 163 INC B 164__EXCL1: 165 LD A,(HL) ;now copy argument string to command line 166 CALL asm_toupper ;make sure they're upper case 167 LD (DE),A 168 INC DE 169 INC HL 170 INC B 171 OR A 172 JP NZ,__EXCL1 173 DEC B 174 175__EXCL2: 176 LD HL,__TBUFF ;set length of command line 177 LD (HL),B ;at location tbuff 178 179 LD DE,__CODE0 ;copy loader down to end of tbuff 180 LD HL,__TPA-42 181 LD B,42 ;length of loader 182__EXCL4: 183 LD A,(DE) 184 LD (HL),A 185 INC DE 186 INC HL 187 DEC B 188 JP NZ,__EXCL4 189 190 POP BC ;get back working fcb pointer 191 LD HL,(__BASE+6) 192 LD SP,HL 193 LD HL,__BASE 194 PUSH HL ;set base of ram as return addr 195 JP __TPA-42 ;(go to `CODE0:') 196; 197; THIS LOADER CODE IS NOW: 42 BYTES LONG. 198; 199__CODE0: 200 LD DE,__TPA ;destination address of new program 201__CODE1: 202 PUSH DE ;push dma addr 203 PUSH BC ;push fcb pointer 204 LD C,__SDMA ;set dma address for new sector 205 CALL __BDOS 206 POP DE ;get pointer to working fcb in de 207 PUSH DE ;and re-push it 208 LD C,__READS ;read a sector 209 CALL __BDOS 210 POP BC ;restore fcb pointer into bc 211 POP DE ;and dma address into de 212 OR A ;end of file? 213 JP Z,__TPA-8 ;if not, get next sector (goto `CODE2:') 214 LD C,__SDMA ;reset dma pointer 215 LD DE,__TBUFF 216 CALL __BDOS 217 JP __TPA ;and go invoke the program 218 219__CODE2: 220 LD HL,80H ; bump dma address 221 ADD HL,DE 222 EX DE,HL 223 JP __TPA-39 ;and go loop (at CODE1) 224 225 226; 227; this routine takes the string pointed to by HL, 228; seperates it into non-white strings, 229; and places them contiguously in array ARGST. 230; also places pointers to these individual strings in ARGS 231; 232__SPARG: 233 EX DE,HL ;DE = original string 234 LD BC,__ARGST ;BC = new string (w/ each substr 0-terminated) 235 LD HL,__ARGS ;HL = pointer to ARGS space 236__SEP0: 237 DEC DE 238__SEP1: 239 INC DE ;scan over white space 240 LD A,(DE) 241 CP ' ' 242 JP Z,__SEP1 243 CP 9 244 JP Z,__SEP1 245 CP 0 ; char = 0? 246 JP Z,__SPRET ; yes -- return 247 LD (HL),C ; no -- store local pointer at proper args 248 INC HL 249 LD (HL),B ;argsn = BC 250 INC HL 251__TOWSP: 252 LD (BC),A ;store non-white 253 INC BC 254 INC DE ;now scan to next white space 255 LD A,(DE) 256 CP 0 257 JP Z,__SEP2 258 CP ' ' 259 JP Z,__SEP2 260 CP 9 261 JP NZ,__TOWSP 262__SEP2: 263 XOR A 264 LD (BC),A ;store 0 to terminate this string 265 INC BC 266 JP __SEP0 ; and loop 267 268__SPRET: 269 LD (HL),A ;set last argn to 0 and return 270 INC HL 271 LD (HL),A 272 RET 273 274 275 276SECTION bss_clib 277 278; 279; Argument pointers 280; 281__ARGS: DEFS 0 282__ARG1: DEFS 2 283__ARG2: DEFS 2 284__ARG3: DEFS 2 285__ARG4: DEFS 2 286__ARG5: DEFS 2 287__ARG6: DEFS 2 288; 289 290__ARGST: 291 DEFS 100 292 293