summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/COMMAND2.ASM
blob: 0f6c5b548a0f641d4274eea750b30636146bb676 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 page 80,132
;	SCCSID = @(#)command2.asm	4.3 85/10/16
;	SCCSID = @(#)command2.asm	4.3 85/10/16
TITLE	COMMAND2 - resident code for COMMAND.COM part II
NAME	COMMAND2
.XCREF
.XLIST
	INCLUDE DOSSYM.INC
	INCLUDE comsw.asm
	INCLUDE comequ.asm
	INCLUDE resmsg.equ		;AN000;
.LIST
.CREF

tokenized = FALSE

CODERES 	SEGMENT PUBLIC BYTE	;AC000;
CODERES ENDS

DATARES SEGMENT PUBLIC BYTE
	EXTRN	append_state:word	;AN020;
	EXTRN	append_flag:byte	;AN020;
	EXTRN	COMDRV:BYTE
	EXTRN	comprmt1_block:byte	;AN000;
	EXTRN	comprmt1_subst:byte	;AN000;
	EXTRN	COMSPEC:BYTE
	EXTRN	cpdrv:byte
	EXTRN	envirseg:word
	EXTRN	EXTCOM:BYTE
	EXTRN	HANDLE01:WORD
	EXTRN	InitFlag:BYTE
	EXTRN	INT_2E_RET:DWORD	;AC000;
	EXTRN	IO_SAVE:WORD
	EXTRN	LOADING:BYTE
	EXTRN	LTPA:WORD
	EXTRN	MEMSIZ:WORD
	EXTRN	number_subst:byte	;AN000;
	EXTRN	OldTerm:DWORD		;AC000;
	EXTRN	PARENT:WORD		;AC000;
	EXTRN	PERMCOM:BYTE
	EXTRN	RDIRCHAR:BYTE
	EXTRN	RES_TPA:WORD
	EXTRN	RETCODE:WORD
	EXTRN	rsrc_xa_seg:word	;AN030;
	EXTRN	RSWITCHAR:BYTE
	EXTRN	SAVE_PDB:WORD
	EXTRN	SINGLECOM:WORD
	EXTRN	SUM:WORD
	EXTRN	TRANS:WORD
	EXTRN	TranVarEnd:BYTE
	EXTRN	TRANVARS:BYTE
	EXTRN	TRNSEG:WORD
	EXTRN	VERVAL:WORD
DATARES ENDS

BATARENA	SEGMENT PUBLIC PARA	;AC000;
BATARENA ENDS

BATSEG		SEGMENT PUBLIC PARA	;AC000;
BATSEG	 ENDS

ENVARENA	SEGMENT PUBLIC PARA	;AC000;
ENVARENA  ENDS

ENVIRONMENT SEGMENT PUBLIC PARA 	; Default COMMAND environment
ENVIRONMENT ENDS

INIT	SEGMENT PUBLIC PARA
	EXTRN	envsiz:word
	EXTRN	oldenv:word
	EXTRN	resetenv:byte
	EXTRN	usedenv:word
INIT	ENDS

TAIL	SEGMENT PUBLIC PARA
TAIL	ENDS

TRANCODE	SEGMENT PUBLIC PARA
TRANCODE	ENDS

TRANDATA	SEGMENT PUBLIC BYTE
	EXTRN	TRANDATAEND:BYTE
TRANDATA	ENDS

TRANSPACE	SEGMENT PUBLIC BYTE
	EXTRN	TRANSPACEEND:BYTE
	EXTRN	HEADCALL:DWORD
TRANSPACE	ENDS

TRANTAIL	SEGMENT PUBLIC PARA
TRANTAIL	ENDS

RESGROUP  GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL

; START OF RESIDENT PORTION

CODERES 	SEGMENT PUBLIC BYTE	;AC000;

	PUBLIC	CHKSUM
	PUBLIC	endinit
	PUBLIC	GETCOMDSK2
	PUBLIC	INT_2E
	PUBLIC	LOADCOM
	PUBLIC	LODCOM
	PUBLIC	LODCOM1
	PUBLIC	RESTHAND
	PUBLIC	SAVHAND
	PUBLIC	SETVECT
	PUBLIC	THEADFIX
	PUBLIC	TREMCHECK
	PUBLIC	tjmp

ASSUME	CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

	EXTRN	contc:near
	EXTRN	DSKERR:NEAR
	EXTRN	rstack:word
;
; If we cannot allocate enough memory for the transient or there was some
; other allocation error, we display a message and then die.
;
BADMEMERR:				; Allocation error loading transient
	MOV	DX,BMEMMES		;AC000; get message number
FATALC:
	PUSH	CS
	POP	DS
	ASSUME	DS:ResGroup
	invoke	RPRINT
;
; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do
; anything else!
;
	CMP	PERMCOM,0
	JZ	FATALRET
;
; We are a permanent command.  If we are in the process of the magic interrupt
; (Singlecom) then exit too.
;
	CMP	SINGLECOM,0		; If PERMCOM and SINGLECOM
	JNZ	FATALRET		; Must take INT_2E exit
;
; Permanent command.  We can't do ANYthing except halt.
;
	MOV	DX,HALTMES		;AC000; get message number
	invoke	RPRINT
	STI
STALL:
	JMP	STALL			; Crash the system nicely

FATALRET:
	MOV	DX,FRETMES		;AC000; get message number
	invoke	RPRINT
FATALRET2:
	CMP	[PERMCOM],0		; If we get here and PERMCOM,
	JNZ	RET_2E			; must be INT_2E
	invoke	reset_msg_pointers	;AN000; reset critical & parse error messages
	MOV	AX,[PARENT]
	MOV	WORD PTR CS:[PDB_Parent_PID],AX
	MOV	AX,WORD PTR OldTerm
	MOV	WORD PTR CS:[PDB_Exit],AX
	MOV	AX,WORD PTR OldTerm+2
	MOV	WORD PTR CS:[PDB_Exit+2],AX
	MOV	AX,(EXIT SHL 8) 	; Return to lower level
	INT	int_command

RET_2E:
	PUSH	CS
	POP	DS
ASSUME	DS:RESGROUP,ES:NOTHING,SS:NOTHING
	MOV	[SINGLECOM],0		; Turn off singlecom
	MOV	ES,[RES_TPA]
	MOV	AH,DEALLOC
	INT	int_command		; Free up space used by transient
	MOV	BX,[SAVE_PDB]
	MOV	AH,SET_CURRENT_PDB
	INT	int_command		; Current process is user
	MOV	AX,[RETCODE]
	CMP	[EXTCOM],0
	JNZ	GOTECODE
	XOR	AX,AX			; Internals always return 0
GOTECODE:
	MOV	[EXTCOM],1		; Force external
	JMP	[INT_2E_RET]		;"IRET"

INT_2E: 				; Magic command executer
ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING
	POP	WORD PTR [INT_2E_RET]
	POP	WORD PTR [INT_2E_RET+2] ;Get return address
	POP	AX			;Chuck flags
	PUSH	CS
	POP	ES
	MOV	DI,80H
	MOV	CX,64
	REP	MOVSW
	MOV	AH,GET_CURRENT_PDB
	INT	int_command		; Get user's header
	MOV	[SAVE_PDB],BX
	MOV	AH,SET_CURRENT_PDB
	MOV	BX,CS
	INT	int_command		; Current process is me
	MOV	[SINGLECOM],81H
	MOV	[EXTCOM],1		; Make sure this case forced

LODCOM: 				; Termination handler
	CMP	[EXTCOM],0
	jz	lodcom1 		; if internal, memory already allocated
	mov	bx,0ffffh
	MOV	AH,ALLOC
	INT	int_command
	CALL	SetSize
	ADD	AX,20H
	CMP	BX,AX			; Is less than 512 byte buffer worth it?
	JNC	MEMOK
BADMEMERRJ:
	JMP BADMEMERR			; Not enough memory

; SetSize - get transient size in paragraphs
Procedure   SetSize,NEAR
	MOV	AX,OFFSET TRANGROUP:TRANSPACEEND + 15
	MOV	CL,4
	SHR	AX,CL
	return
EndProc SetSize

MEMOK:
	MOV	AH,ALLOC
	INT	int_command
	JC	BADMEMERRJ		; Memory arenas probably trashed
	MOV	[EXTCOM],0		; Flag not to ALLOC again
	MOV	[RES_TPA], AX		; Save current TPA segment
	AND	AX, 0F000H
	ADD	AX, 01000H		; Round up to next 64K boundary
	JC	BAD_TPA 		; Memory wrap if carry set
; Make sure that new boundary is within allocated range
	MOV	DX, [RES_TPA]
	ADD	DX, BX			; Compute maximum address
	CMP	DX, AX			; Is 64K address out of range?
	JBE	BAD_TPA
; Must have 64K of usable space.
	SUB	DX, AX			; Compute the usable space
	CMP	DX, 01000H		; Is space >= 64K ?
	JAE	LTPASET
BAD_TPA:
	MOV	AX, [RES_TPA]
LTPASET:
	MOV	[LTPA],AX		; Usable TPA is 64k buffer aligned
	MOV	AX, [RES_TPA]		; Actual TPA is buffer allocated
	ADD	BX,AX
	MOV	[MEMSIZ],BX
	CALL	SetSize
	SUB	BX,AX
	MOV	[TRNSEG],BX		; Transient starts here
LODCOM1:
	MOV	AX,CS
	MOV	SS,AX
ASSUME	SS:RESGROUP
	MOV	SP,OFFSET RESGROUP:RSTACK
	MOV	DS,AX
ASSUME	DS:RESGROUP
	CALL	HEADFIX 		; Make sure files closed stdin and stdout restored
	XOR	BP,BP			; Flag command ok
	MOV	AX,-1
	XCHG	AX,[VERVAL]
	CMP	AX,-1
	JZ	NOSETVER
	MOV	AH,SET_VERIFY_ON_WRITE	; AL has correct value
	INT	int_command
NOSETVER:
	CMP	[SINGLECOM],-1
	JNZ	NOSNG
	JMP	FATALRET2		; We have finished the single command
NOSNG:
	CALL	CHKSUM			; Check the transient
	CMP	DX,[SUM]
	JZ	HAVCOM			; Transient OK
BOGUS_COM:
	MOV	[LOADING],1		; Flag DSKERR routine
	CALL	LOADCOM
CHKSAME:

	CALL	CHKSUM
	CMP	DX,[SUM]
	JZ	HAVCOM			; Same COMMAND
ALSO_BOGUS:
	CALL	WRONGCOM
	JMP	SHORT CHKSAME
HAVCOM:
	MOV	AX,CHAR_OPER SHL 8
	INT	int_command
	MOV	[RSWITCHAR],DL
	CMP	DL,'/'
	JNZ	USESLASH
	mov	cl,'\'
	MOV	[RDIRCHAR],cl		; Select alt path separator
USESLASH:
	MOV	[LOADING],0		; Flag to DSKERR
	MOV	SI,OFFSET RESGROUP:TRANVARS
	MOV	DI,OFFSET TRANGROUP:HEADCALL
	MOV	ES,[TRNSEG]
	CLD
	MOV	CX,OFFSET ResGroup:TranVarEnd
	SUB	CX,SI
	REP	MOVSB			; Transfer INFO to transient
	MOV	AX,[MEMSIZ]
	MOV	WORD PTR DS:[PDB_block_len],AX	; Adjust my own header

; Just a public label so this spot can be found easily.
tjmp:
	JMP	DWORD PTR [TRANS]

; Far call to REMCHECK for TRANSIENT
TREMCHECK PROC	 FAR
	CALL	REMCHECK
	RET
TREMCHECK ENDP

REMCHECK:
;All registers preserved. Returns ZF set if media removable, NZ if fixed
; AL is drive (0=DEF, 1=A,...).
	SaveReg <AX,BX>
	MOV	BX,AX
	MOV	AX,(IOCTL SHL 8) + 8
	INT	21h
	jnc	RCcont			; If an error occurred, assume the media
	or	ax,ax			;  is NON-removable.
					;  AX contains the non-zero error code
					;  from the INT 21, so the OR AX,AX sets
					;  Non-zero. This behavior makes Network
					;  drives appear to be non-removable.
	jmp	SHORT ResRegs
RCcont:
	AND	AX,1
	NOT	AX
ResRegs:
	RestoreReg  <BX,AX>
	return

; Far call to HEADFIX for TRANSIENT
THEADFIX PROC	FAR
	CALL	HEADFIX
	RET
THEADFIX ENDP

HEADFIX:
	CALL	SETVECT
	XOR	BX,BX			; Clean up header
	MOV	CX,[IO_SAVE]
	MOV	DX,WORD PTR DS:[PDB_JFN_Table]
	CMP	CL,DL
	JZ	CHK1			; Stdin matches
	MOV	AH,CLOSE
	INT	int_command
	MOV	DS:[PDB_JFN_Table],CL	; Restore stdin
CHK1:
	INC	BX
	CMP	CH,DH			; Stdout matches
	JZ	CHKOTHERHAND
	MOV	AH,CLOSE
	INT	int_command
	MOV	DS:[PDB_JFN_Table+1],CH ; Restore stdout
CHKOTHERHAND:
	ADD	BX,4			; Skip 2,3,4
	MOV	CX,FilPerProc - 5	; Already done 0,1,2,3,4
CLOSELOOP:
	MOV	AH,CLOSE
	INT	int_command
	INC	BX
	LOOP	CLOSELOOP
	push	ds			;AN020; save data segment
	push	cs			;AN020; Get local segment into DS
	pop	ds			;AN020;
	cmp	append_flag,-1		;AN020; Do we need to reset APPEND?
	jnz	append_fix_end		;AN030; no - just exit
	mov	ax,AppendSetState	;AN020; Set the state of Append
	mov	bx,Append_state 	;AN020;     back to the original state
	int	2fh			;AN020;
	mov	append_flag,0		;AN020; Set append flag to invalid
append_fix_end: 			;AN030;
	cmp	[rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment?
	jz	xa_fix_end		;AN030; no - exit
	push	es			;AN030; Yes - deallocate it
	mov	es,rsrc_xa_seg		;AN030;
	mov	ax,(Dealloc SHL 8)	;AN030; Deallocate memory call
	int	int_command		;AN030;
	pop	es			;AN030;
	mov	[rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
xa_fix_end:
	pop	ds			;AN020; get data segment back
	return

SAVHAND:
ASSUME	DS:NOTHING,ES:NOTHING,SS:NOTHING
	PUSH	DS
	PUSH	BX			; Set stdin to sterr, stdout to stderr
	PUSH	AX
	MOV	AH,GET_CURRENT_PDB
	INT	int_command		; Get user's header
	MOV	DS,BX
	LDS	BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
	MOV	AX,WORD PTR DS:[BX]
	MOV	[HANDLE01],AX		; Save user's stdin, stdout
	MOV	AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr
	MOV	AH,AL
	MOV	WORD PTR DS:[BX],AX	; Dup stderr
	POP	AX
	POP	BX
	POP	DS
	return

ASSUME	DS:RESGROUP
GETCOMDSK2:
	CALL	GETCOMDSK
	JMP	LODCOM1 		; Memory already allocated

RESTHAND:
	PUSH	DS
	PUSH	BX			; Restore stdin, stdout to user
	PUSH	AX
	MOV	AH,GET_CURRENT_PDB
	INT	int_command		; Point to user's header
	MOV	AX,[HANDLE01]
	MOV	DS,BX
ASSUME DS:NOTHING
	LDS	BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
	MOV	WORD PTR DS:[BX],AX	; Stuff his old 0 and 1
	POP	AX
	POP	BX
	POP	DS
	return
ASSUME DS:RESGROUP,SS:RESGROUP

HOPELESS:
	MOV	DX,COMBAD		;AC000;
	JMP	FATALC

GETCOMDSK:
	mov	al,[comdrv]
	CALL	REMCHECK
	jNZ	HOPELESS		;Non-removable media
getcomdsk3:
	cmp	dx,combad		;AC000;
	jnz	getcomdsk4
	mov	dx,combad		;AN000; get message number
	invoke	RPRINT			; Say command is invalid
getcomdsk4:
	cmp	[cpdrv],0		;g is there a drive in the comspec?
	jnz	users_drive		;g yes - use it
	mov	ah,Get_default_drive	;g use default drive
	int	21h			;g
	add	al,"A"                  ;g convert to ascii
	mov	[cpdrv],al		;g put in message to print out

users_drive:				;g
	mov	dx,comprmt1		;AC000; Prompt for diskette containing command
IF tokenized
	or	byte ptr [si],80h
endif
	MOV	AL,COMPRMT1_SUBST	;AN000; get number of substitutions
	MOV	SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block
	MOV	NUMBER_SUBST,AL 	;AN000;
	invoke	rprint
if tokenized
	and	byte ptr [si],NOT 80h
endif
	mov	dx,prompt		;AN047; Tell the user to strike a key
	invoke	rprint			;AN047;
	CALL	GetRawFlushedByte
	return

; flush world and get raw input
GetRawFlushedByte:
	MOV	AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
	INT	int_command		; Get char without testing or echo
	MOV	AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
	INT	int_command
	return

LOADCOM:				; Load in transient
	INC	BP			; Flag command read
	MOV	DX,OFFSET RESGROUP:COMSPEC
	MOV	AX,OPEN SHL 8
	INT	int_command		; Open COMMAND.COM
	JNC	READCOM
	CMP	AX,error_too_many_open_files
	JNZ	TRYDOOPEN
	MOV	DX,NOHANDMES		;AC000;
	JMP	FATALC			; Fatal, will never find a handle

TRYDOOPEN:
	CALL	GETCOMDSK
	JMP	LOADCOM

READCOM:
	MOV	BX,AX			; Handle
	MOV	DX,OFFSET RESGROUP:TRANSTART
	XOR	CX,CX			; Seek loc
	MOV	AX,LSEEK SHL 8
	INT	int_command
	JC	WRONGCOM1
	MOV	CX,OFFSET TRANGROUP:TRANSPACEEND - 100H

	PUSH	DS
	MOV	DS,[TRNSEG]
ASSUME	DS:NOTHING
	MOV	DX,100H
	MOV	AH,READ
	INT	int_command
	POP	DS
ASSUME	DS:RESGROUP
WRONGCOM1:
	PUSHF
	PUSH	AX
	MOV	AH,CLOSE
	INT	int_command		; Close COMMAND.COM
	POP	AX
	POPF
	JC	WRONGCOM		; If error on READ
	CMP	AX,CX
	retz				; Size matched
WRONGCOM:
	MOV	DX,COMBAD		;AC000;
	CALL	GETCOMDSK
	JMP	LOADCOM 		; Try again

CHKSUM: 				; Compute transient checksum
	PUSH	DS
	MOV	DS,[TRNSEG]
	MOV	SI,100H
	MOV	CX,OFFSET TRANGROUP:TranDataEnd  - 100H

CHECK_SUM:
	CLD
	SHR	CX,1
	XOR	DX,DX
CHK:
	LODSW
	ADD	DX,AX
	ADC	DX,0
	LOOP	CHK
	POP	DS
	return

SETVECT:				; Set useful vectors
	MOV	DX,OFFSET RESGROUP:LODCOM
	MOV	AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H
	MOV	WORD PTR DS:[PDB_EXIT],DX
	MOV	WORD PTR DS:[PDB_EXIT+2],DS
	INT	int_command
	MOV	DX,OFFSET RESGROUP:CONTC
	INC	AL
	INT	int_command
	MOV	DX,OFFSET RESGROUP:DSKERR
	INC	AL
	INT	int_command
	return


;
;  This routine moves the environment to a newly allocated segment
;  at the end of initialization
;

ENDINIT:
	push	ds			;g save segments
	push	es			;g
	push	cs			;g get resident segment to DS
	pop	ds			;g
	ASSUME	DS:RESGROUP
	mov	cx,usedenv		;g get number of bytes to move
	mov	es,envirseg		;g get target environment segment

	ASSUME	ES:NOTHING
	mov	DS:[PDB_environ],es	;g put new environment in my header	   ;AM067;
	mov	ds,oldenv		;g source environment segment		   ;AM067;
	ASSUME	DS:NOTHING							   ;AM067;
	xor	si,si			;g set up offsets to start of segments	   ;AM067;
	xor	di,di			;g					   ;AM067;
	cld				;g make sure we move the right way!	   ;AM067;
	rep	movsb			;g move it				   ;AM067;
	xor	ax,ax			;g					   ;AM067;
	stosb				;g make sure there are double 0 at end	   ;AM067;

	cmp	resetenv,1		;eg Do we need to setblock to env end?
	jnz	noreset 		;eg no - we already did it
	mov	bx,envsiz		;eg get size of environment in paragraphs
	push	es			;eg save environment - just to make sure
	mov	ah,SETBLOCK		;eg
	int	int_command		;eg
	pop	es			;eg

noreset:
	mov	InitFlag,FALSE		;AC042; Turn off init flag
	pop	es			;g
	pop	ds			;g
	jmp	lodcom			;g allocate transient

CODERES ENDS

; This TAIL segment is used to produce a PARA aligned label in the resident
; group which is the location where the transient segments will be loaded
; initial.

TAIL	SEGMENT PUBLIC PARA
	ORG	0
	PUBLIC	TranStart
TRANSTART	LABEL	WORD
TAIL	ENDS

; This TAIL segment is used to produce a PARA aligned label in the transient
; group which is the location where the exec segments will be loaded
; initial.

TRANTAIL    SEGMENT PUBLIC PARA
	ORG	0
EXECSTART   LABEL   WORD
TRANTAIL    ENDS

	END