Subversion Repositories SvarDOS

Rev

Rev 460 | Rev 463 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 460 Rev 461
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
; offset where a program name to be executed is awaiting (0=none)
-
 
25
; this is set by SvarCOM, after it presets the ExecParamRec struct and
-
 
26
; stores the command to be executed somewhere within rmod's segment.
-
 
27
EXECPROG dw 0    ;  +8
24
FFU_UNUSED dw 0  ;  +8
28
 
25
 
29
; exit code of last application
26
; exit code of last application
30
LEXCODE  dw 0    ; +0Ah
27
LEXCODE  dw 0    ; +0Ah
31
 
28
 
32
; 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
33
; 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
34
COMSPECPTR dw 0  ; +0Ch
31
COMSPECPTR dw 0  ; +0Ch
35
 
32
 
36
; 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
37
; drive. drive is patched by the transient part of COMMAND.COM
34
; drive. drive is patched by the transient part of COMMAND.COM
38
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh
35
COMSPECBOOT db "@:\COMMAND.COM", 0 ; +0Eh
39
 
36
 
40
; 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:
41
;  offset  size  content
38
;  offset  size  content
42
;     +0     2   segment of environment for child (0 = current)
39
;     +0     2   segment of environment for child (0 = current)
43
;     +2     4   address of command line to place at PSP:0080
40
;     +2     4   address of command line to place at PSP:0080
44
;     +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
45
;    +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
46
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
47
 
44
 
-
 
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
-
 
47
 
48
skipsig:         ; +2Bh
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: most probably I should call the DOS SetPSP function here
61
; TODO: perhaps I should call the DOS SetPSP function here? But if I do, the
-
 
62
;       int 21h, ah=50h call freezes...
-
 
63
;mov ah, 0x50           ; DOS 2+ -- Set PSP
-
 
64
;mov bx, cs
-
 
65
;int 0x21
62
 
66
 
63
; exec an application preset (by SvarCOM) in the ExecParamRec
67
; exec an application preset (by SvarCOM) in the ExecParamRec
64
mov [EXECPROG], byte 0 ; make sure to spawn command.com after app exits
-
 
65
mov ax, 0x4B00         ; DOS 2+ - load & execute program
68
mov ax, 0x4B00         ; DOS 2+ - load & execute program
66
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)
67
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
70
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
68
int 0x21
71
int 0x21
-
 
72
mov [EXECPROG], byte 0 ; make sure to spawn command.com after app exits
69
 
73
 
70
EXEC_COMMAND_COM:
74
EXEC_COMMAND_COM:
71
 
75
 
72
; collect the exit code of previous application
76
; collect the exit code of previous application
73
mov ah, 0x4D
77
mov ah, 0x4D
74
int 0x21
78
int 0x21
75
xor ah, ah          ; clear out termination status, I only want the exit code
79
xor ah, ah          ; clear out termination status, I only want the exit code
76
mov [LEXCODE], ax
80
mov [LEXCODE], ax
77
 
81
 
78
; zero out the exec param block (14 bytes)
82
; zero out the exec param block (14 bytes)
79
mov al, 0              ; byte to write
83
mov al, 0              ; byte to write
80
mov cx, 14             ; how many times
84
mov cx, 14             ; how many times
81
mov di, EXEC_PARAM_REC ; ES:DI = destination
85
mov di, EXEC_PARAM_REC ; ES:DI = destination
82
cld                    ; stosb must move forward
86
cld                    ; stosb must move forward
83
rep stosb              ; repeat cx times
87
rep stosb              ; repeat cx times
84
 
88
 
85
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS)
89
; preset the default COMSPEC pointer to ES:DX (ES is already set to DS)
86
mov dx, COMSPECBOOT
90
mov dx, COMSPECBOOT
87
 
91
 
88
; do I have a valid COMSPEC?
92
; do I have a valid COMSPEC?
89
or [COMSPECPTR], word 0
93
or [COMSPECPTR], word 0
90
jz USEDEFAULTCOMSPEC
94
jz USEDEFAULTCOMSPEC
91
; set ES:DX to actual COMSPEC (in env segment)
95
; set ES:DX to actual COMSPEC (in env segment)
92
mov es, [PSP_ENVSEG]
96
mov es, [PSP_ENVSEG]
93
mov dx, [COMSPECPTR]
97
mov dx, [COMSPECPTR]
94
USEDEFAULTCOMSPEC:
98
USEDEFAULTCOMSPEC:
95
 
99
 
96
; prepare the exec param block
100
; prepare the exec param block
97
mov ax, [PSP_ENVSEG]
101
mov ax, [PSP_ENVSEG]
98
mov [EXEC_PARAM_REC], ax
102
mov [EXEC_PARAM_REC], ax
99
mov ax, CMDTAIL
103
mov ax, CMDTAIL
100
mov [EXEC_PARAM_REC+2], ax
104
mov [EXEC_PARAM_REC+2], ax
101
mov [EXEC_PARAM_REC+4], cs
105
mov [EXEC_PARAM_REC+4], cs
102
 
106
 
103
; execute command.com
107
; execute command.com
104
mov ax, 0x4B00         ; DOS 2+ - load & execute program
108
mov ax, 0x4B00         ; DOS 2+ - load & execute program
105
push es                ;
109
push es                ;
106
pop ds                 ;
110
pop ds                 ;
107
;mov dx, COMSPEC       ; DS:DX  - ASCIZ program name (preset already)
111
;mov dx, COMSPEC       ; DS:DX  - ASCIZ program name (preset already)
108
push cs
112
push cs
109
pop es
113
pop es
110
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
114
mov bx, EXEC_PARAM_REC ; ES:BX  - parameter block pointer
111
int 0x21
115
int 0x21
112
 
116
 
113
; if all went well, jump back to start
117
; if all went well, jump back to start
114
jnc skipsig
118
jnc skipsig
115
 
119
 
116
; restore DS=CS
120
; restore DS=CS
117
mov bx, cs
121
mov bx, cs
118
mov ds, bx
122
mov ds, bx
119
 
123
 
120
; update error string so it contains the error number
124
; update error string so it contains the error number
121
add al, '0'
125
add al, '0'
122
mov [ERRLOAD + 4], al
126
mov [ERRLOAD + 4], al
123
 
127
 
124
; display error message
128
; display error message
125
mov ah, 0x09
129
mov ah, 0x09
126
mov dx, ERRLOAD
130
mov dx, ERRLOAD
127
int 0x21
131
int 0x21
128
 
132
 
129
; wait for keypress
133
; wait for keypress
130
mov ah, 0x08
134
mov ah, 0x08
131
int 0x21
135
int 0x21
132
 
136
 
133
; back to program start
137
; back to program start
134
jmp skipsig
138
jmp skipsig
135
 
139
 
136
; command.com tail arguments, in PSP format: length byte followed by args and
140
; command.com tail arguments, in PSP format: length byte followed by args and
137
; terminated with \r)
141
; terminated with \r)
138
CMDTAIL db 0x00, 0x0D
142
CMDTAIL db 0x00, 0x0D
139
 
143
 
140
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$'
144
ERRLOAD db "ERR x, FAILED TO LOAD COMMAND.COM", 13, 10, '$'
141
 
145
 
142
; DOS int 21h functions that I use require at least 32 bytes of stack, here I
146
; DOS int 21h functions that I use require at least 32 bytes of stack, here I
143
; allocate 64 bytes to be sure
147
; allocate 64 bytes to be sure
144
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
148
STACKBUF db "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
145
STACKPTR db "xx"
149
STACKPTR db "xx"
146
 
150