Subversion Repositories SvarDOS

Rev

Rev 465 | Rev 517 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
349 mateuszvis 1
;
2
; rmod - resident module of the SvarCOM command interpreter
3
;
4
; Copyright (C) 2021 Mateusz Viste
5
; MIT license
6
;
7
; this is installed in memory by the transient part of SvarCOM. it has only
8
; two jobs: providing a resident buffer for command history, environment, etc
9
; and respawning COMMAND.COM whenever necessary.
10
 
11
CPU 8086
459 mateuszvis 12
org 0x100
349 mateuszvis 13
 
459 mateuszvis 14
PSP_ENVSEG equ 0x2C
15
 
349 mateuszvis 16
section .text    ; all goes into code segment
17
 
350 mateuszvis 18
                 ; offset
19
SIG1 dw 0x1983   ;  +0
20
SIG2 dw 0x1985   ;  +2
21
SIG3 dw 0x2017   ;  +4
490 mateuszvis 22
SIG4 dw 0x2019   ;  +6  this acts also as a guardval to detect stack overflows
349 mateuszvis 23
 
490 mateuszvis 24
; DOS int 21h functions that I use require at least 40 bytes of stack under
25
; DOS-C (FreeDOS) kernel, so here I reserve 64 bytes juste to be sure
26
STACKBUF db "XXX  SVARCOM RMOD BY MATEUSZ VISTE  XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
27
STACKPTR dw 0
349 mateuszvis 28
 
353 mateuszvis 29
; exit code of last application
490 mateuszvis 30
LEXCODE  dw 0    ; +4Ah
353 mateuszvis 31
 
366 mateuszvis 32
; offset of the COMSPEC variable in the environment block, 0 means "use
33
; boot drive". this value is patched by the transient part of COMMAND.COM
490 mateuszvis 34
COMSPECPTR dw 0  ; +4Ch
349 mateuszvis 35
 
366 mateuszvis 36
; fallback COMSPEC string used if no COMPSEC is present in the environment
37
; drive. drive is patched by the transient part of COMMAND.COM
490 mateuszvis 38
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +4Eh
350 mateuszvis 39
 
460 mateuszvis 40
; ExecParamRec used by INT 21h, AX=4b00 (load and execute program), 14 bytes:
41
;  offset  size  content
42
;     +0     2   segment of environment for child (0 = current)
43
;     +2     4   address of command line to place at PSP:0080
44
;     +6     4   address of an FCB to be placed at PSP:005c
45
;    +0Ah    4   address of an FCB to be placed at PSP:006c
490 mateuszvis 46
EXEC_PARAM_REC db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0   ; +5Dh
366 mateuszvis 47
 
490 mateuszvis 48
; Program to execute, preset by SvarCOM (128 bytes, ASCIIZ)  ; +6Bh
461 mateuszvis 49
EXECPROG dd 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
460 mateuszvis 50
 
490 mateuszvis 51
skipsig:         ; +EBh
461 mateuszvis 52
 
349 mateuszvis 53
; set up CS=DS=SS and point SP to my private stack buffer
54
mov ax, cs
55
mov ds, ax
56
mov es, ax
57
mov ss, ax
58
mov sp, STACKPTR
59
 
460 mateuszvis 60
; should I executed command.com or a pre-set application?
61
or [EXECPROG], byte 0
62
jz EXEC_COMMAND_COM
63
 
461 mateuszvis 64
; TODO: perhaps I should call the DOS SetPSP function here? But if I do, the
65
;       int 21h, ah=50h call freezes...
66
;mov ah, 0x50           ; DOS 2+ -- Set PSP
67
;mov bx, cs
68
;int 0x21
460 mateuszvis 69
 
70
; exec an application preset (by SvarCOM) in the ExecParamRec
71
mov ax, 0x4B00         ; DOS 2+ - load & execute program
461 mateuszvis 72
mov dx, EXECPROG       ; DS:DX  - ASCIZ program name (preset at PSP[already)
460 mateuszvis 73
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
74
int 0x21
465 mateuszvis 75
mov [cs:EXECPROG], byte 0 ; do not run app again (+DS might have been changed)
460 mateuszvis 76
 
463 mateuszvis 77
jmp short skipsig      ; enforce valid ds/ss/etc (can be lost after int 21,4b)
78
 
460 mateuszvis 79
EXEC_COMMAND_COM:
80
 
353 mateuszvis 81
; collect the exit code of previous application
82
mov ah, 0x4D
83
int 0x21
84
xor ah, ah          ; clear out termination status, I only want the exit code
85
mov [LEXCODE], ax
86
 
460 mateuszvis 87
; zero out the exec param block (14 bytes)
88
mov al, 0              ; byte to write
89
mov cx, 14             ; how many times
90
mov di, EXEC_PARAM_REC ; ES:DI = destination
91
cld                    ; stosb must move forward
92
rep stosb              ; repeat cx times
93
 
366 mateuszvis 94
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS)
95
mov dx, COMSPECBOOT
96
 
97
; do I have a valid COMSPEC?
98
or [COMSPECPTR], word 0
99
jz USEDEFAULTCOMSPEC
459 mateuszvis 100
; set ES:DX to actual COMSPEC (in env segment)
101
mov es, [PSP_ENVSEG]
366 mateuszvis 102
mov dx, [COMSPECPTR]
103
USEDEFAULTCOMSPEC:
104
 
349 mateuszvis 105
; prepare the exec param block
459 mateuszvis 106
mov ax, [PSP_ENVSEG]
350 mateuszvis 107
mov [EXEC_PARAM_REC], ax
465 mateuszvis 108
mov [EXEC_PARAM_REC+2], word CMDTAIL
442 mateuszvis 109
mov [EXEC_PARAM_REC+4], cs
349 mateuszvis 110
 
111
; execute command.com
112
mov ax, 0x4B00         ; DOS 2+ - load & execute program
366 mateuszvis 113
push es                ;
114
pop ds                 ;
115
;mov dx, COMSPEC       ; DS:DX  - ASCIZ program name (preset already)
116
push cs
117
pop es
349 mateuszvis 118
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
119
int 0x21
120
 
121
; if all went well, jump back to start
122
jnc skipsig
123
 
366 mateuszvis 124
; restore DS=CS
125
mov bx, cs
126
mov ds, bx
127
 
349 mateuszvis 128
; update error string so it contains the error number
129
add al, '0'
130
mov [ERRLOAD + 4], al
131
 
366 mateuszvis 132
; display error message
349 mateuszvis 133
mov ah, 0x09
134
mov dx, ERRLOAD
135
int 0x21
136
 
137
; wait for keypress
138
mov ah, 0x08
139
int 0x21
140
 
141
; back to program start
142
jmp skipsig
143
 
460 mateuszvis 144
; command.com tail arguments, in PSP format: length byte followed by args and
465 mateuszvis 145
; terminated with \r) - a single 0x0A byte is passed so SvarCOM knows it is
146
; called as respawn (as opposed to being invoked as a normal application)
147
; this allows multiple copies of SvarCOM to stack upon each other.
148
CMDTAIL db 0x01, 0x0A, 0x0D
442 mateuszvis 149
 
366 mateuszvis 150
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$'