summaryrefslogtreecommitdiff
path: root/v4.0/src/INC/MSHALO.ASM
blob: 65b46d587d41f4752bb13f26870834205de952a2 (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
;	SCCSID = @(#)ibmhalo.asm	1.1 85/04/10
;   On 2K (800h) boundaries beginning at address C0000h and ending at EF800h
;   there is a header that describes a block of rom program.  This header
;   contains information needed to initialize a module and to provide PCDOS
;   with a set of reserved names for execution.
;
;   This header has the following format:
;
;   rom_header	STRUC
;	Signature1  DB	55h
;	Signature2  DB	AAh
;	rom_length  DB	?		; number of 512 byte pieces
;	init_jmp    DB	3 dup (?)
;	name_list   name_struc <>
;   rom_header	ENDS
;
;   name_struc	STRUC
;	name_len    DB	?
;	name_text   DB	? DUP (?)
;	name_jmp    DB	3 DUP (?)
;   name_struc	ENDS
;
;   The name list is a list of names that are reserved by a particular section
;   of a module.  This list of names is terminated by a null name (length
;   is zero).
;
;   Consider now, the PCDOS action when a user enters a command:
;
;	COMMAND.COM has control.
;	o   If location FFFFEh has FDh then
;	o	Start scanning at C0000h, every 800h for a byte 55h followed
;		    by AAh, stop scan if we get above or = F0000H
;	o	When we've found one, compare the name entered by the user
;		    with the one found in the rom.  If we have a match, then
;		    set up the environment for execution and do a long jump
;		    to the near jump after the found name.
;	o	If no more names in the list, then continue scanning the module
;		    for more 55h followed by AAh.
;	o   We get to this point only if there is no matching name in the
;		rom.  We now look on disk for the command.
;
;   This gives us the flexibility to execute any rom cartridge without having
;   to 'hard-code' the name of the cartridge into PCDOS.  Rom modules that
;   want to be invisible to the DOS should not have any names in their lists
;   (i.e. they have a single null name).
;
;   Consider a new release of BASIC, say, that patches bugs in the ROM version.
;   Clearly this version will be available on disk.  How does a user actually
;   invoke this new BASIC??  He cannot call it BASIC on the disk because the
;   EXEC loader will execute the ROM before it even looks at the disk!	Only
;   solution:
;
;   o	Keep things consistent and force the user to have his software named
;	differently from the ROM names (BASIC1, BASIC2, etc).

rom_header  STRUC
    Signature1	DB  ?
    Signature2	DB  ?
    rom_length	DB  ?
    init_jmp	DB  3 dup (?)
    name_list	DB  ?
rom_header  ENDS

name_struc  STRUC
    name_len	DB  ?
    name_text	DB  1 DUP (?)
    name_jmp	DB  3 DUP (?)
name_struc  ENDS

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

;
; Check for IBM PC Jr rom cartrides. DS:DX is a pointer to name
;
ROM_SCAN:
	PUSH	ES
	PUSH	SI
	PUSH	DI
	PUSH	CX
	PUSH	AX
	PUSH	BX
;
; check for PC Jr signature in rom
;
	MOV	AX,0F000h
	MOV	ES,AX
	CMP	BYTE PTR ES:[0FFFEh],0FDh
	JZ	SCAN_IT
NO_ROM:
	CLC
ROM_RET:
	POP	BX
	POP	AX
	POP	CX
	POP	DI
	POP	SI
	POP	ES
	RET
SCAN_IT:
;
; start scanning at C000
;
	MOV	AX,0C000h
SCAN_ONE:
	MOV	ES,AX
	XOR	DI,DI
SCAN_MODULE:
;
; check for a valid header
;
	CMP	WORD PTR ES:[DI],0AA55h
	JZ	SCAN_LIST
	ADD	AX,080h
SCAN_END:
	CMP	AX,0F000h
	JB	SCAN_ONE
	JMP	NO_ROM
;
; trundle down list of names
;
SCAN_LIST:
	MOV	BL,ES:[DI].rom_length	; number of 512-byte jobbers
	XOR	BH,BH			; nothing in the high byte
	SHL	BX,1
	SHL	BX,1			; number of paragraphs
	ADD	BX,7Fh
	AND	BX,0FF80h		; round to 2k

	MOV	DI,name_list
SCAN_NAME:
	MOV	CL,ES:[DI]		; length of name
	INC	DI			; point to name
	XOR	CH,CH
	OR	CX,CX			; zero length name
	JNZ	SCAN_TEST		; nope... compare
	ADD	AX,BX			; yep, skip to next block
	JMP	SCAN_END
;
; compare a single name
;
SCAN_TEST:
	MOV	SI,DX
	INC	SI
	REPE	CMPSB			; compare name
	JZ	SCAN_FOUND		; success!
SCAN_NEXT:
	ADD	DI,CX			; failure, next name piece
	ADD	DI,3
	JMP	SCAN_NAME
;
; found a name. save entry location
;
SCAN_FOUND:
	CMP	BYTE PTR DS:[SI],'?'
	JZ	SCAN_SAVE
	CMP	BYTE PTR DS:[SI],' '
	JNZ	SCAN_NEXT
SCAN_SAVE:
	MOV	[rom_cs],ES
	MOV	[ROM_ip],DI
	STC
	JMP	ROM_RET

;
; execute a rom-placed body of code. allocate largest block
;
ROM_EXEC:
	MOV	BX,0FFFFh
	MOV	AH,ALLOC
	INT	int_command
	MOV	AH,ALLOC
	INT	int_command
	PUSH	BX
	PUSH	AX
;
; set terminate addresses
;
	MOV	AX,(set_interrupt_vector SHL 8) + int_terminate
	PUSH	DS
	MOV	DS,[RESSEG]
	ASSUME	DS:RESGROUP
	MOV	DX,OFFSET RESGROUP:EXEC_WAIT
	INT	int_command
	MOV	DX,DS
	MOV	ES,DX
	ASSUME	ES:RESGROUP
	POP	DS
	ASSUME	DS:NOTHING
;
; and create program header and dup all jfn's
;
	POP	DX
	MOV	AH,DUP_PDB
	INT	int_command
;
; set up dma address
;
	MOV	DS,DX
	MOV	DX,080h
	MOV	AH,SET_DMA
	INT	int_command
;
; copy in environment info
;
	MOV	AX,[ENVIRSEG]
	MOV	DS:[PDB_environ],AX
;
; set up correct size of block
;
	POP	BX			; BX has size, DS has segment
	MOV	DX,DS
	ADD	DX,BX
	MOV	DS:[PDB_block_len],DX
;
; change ownership of block
;
	MOV	DX,DS
	DEC	DX
	MOV	DS,DX
	INC	DX
	MOV	DS:[arena_owner],DX
	MOV	DS,DX
;
; set up correct stack
;
	CMP	BX,1000h
	JB	GOT_STACK
	XOR	BX,BX
GOT_STACK:
	MOV	CL,4
	SHL	BX,CL
	MOV	DX,DS
	MOV	SS,DX
	MOV	SP,BX
	XOR	AX,AX
	PUSH	AX
;
; set up initial registers and go to the guy
;
	NOT	AX
	PUSH	[ROM_CS]
	PUSH	[ROM_IP]
	MOV	ES,DX
ASSUME ES:NOTHING
FOOBAR	PROC	FAR
	RET
FOOBAR	ENDP