Subversion Repositories SvarDOS

Rev

Rev 461 | Rev 465 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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