forked from fysnet/i440fx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathescd.asm
315 lines (267 loc) · 11.3 KB
/
escd.asm
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
comment |*******************************************************************
* Copyright (c) 1984-2025 Forever Young Software Benjamin David Lunt *
* *
* i440FX BIOS ROM v1.0 *
* FILE: escd.asm *
* *
* This code is freeware, not public domain. Please use respectfully. *
* *
* You may: *
* - use this code for learning purposes only. *
* - use this code in your own Operating System development. *
* - distribute any code that you produce pertaining to this code *
* as long as it is for learning purposes only, not for profit, *
* and you give credit where credit is due. *
* *
* You may NOT: *
* - distribute this code for any purpose other than listed above. *
* - distribute this code for profit. *
* *
* You MUST: *
* - include this whole comment block at the top of this file. *
* - include contact information to where the original source is located. *
* https://github.com/fysnet/i440fx *
* *
* DESCRIPTION: *
* escd include file *
* *
* BUILT WITH: NewBasic Assembler *
* http://www.fysnet/newbasic.htm *
* NBASM ver 00.27.15 *
* Command line: nbasm i440fx /z<enter> *
* *
* Last Updated: 5 Jan 2025 *
* *
****************************************************************************
* Notes: *
* *
***************************************************************************|
FLASH_READ_ARRAY equ 0xFF
FLASH_INT_ID equ 0x90
FLASH_READ_STATUS equ 0x70
FLASH_CLR_STATUS equ 0x50
FLASH_ERASE_SETUP equ 0x20
FLASH_ERASE_SUSP equ 0xB0
FLASH_PROG_SETUP equ 0x40
FLASH_ERASE equ 0xD0
ESCD_DATA_SIZE equ 0x1800
ESCD_DATA_TOT_SIZE equ 0x2000 ; must not be more than 32k
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; the following is the format of the ESCD that we use.
; the first part is specification correct, while the last part is this bios defined.
; (not more than ESCD_DATA_TOT_SIZE bytes in size)
ESCD_DATA struct
size word ; size of the 'ESCD correct' data (right now, just this header = 12)
signature dword ; "ACFG"
minor_ver byte ; minor version number
major_ver byte ; major version number (0x02)
board_cnt byte ; number of board entries
resv0 dup 3 ; reserved
; the ESCD now can store up to ESCD_DATA_TOT_SIZE (minus the header and anything we have below).
; To let the Guest store things here for faster booting, we reserved these
; bytes and set them to zero. The OS will modify them as it see's fit.
; (we allow ESCD_DATA_SIZE - 12 bytes here)
brdhdrs dup (ESCD_DATA_SIZE - 12)
; data items specific to this bios (non-ESCD specs stuff)
; (ESCD_DATA_TOT_SIZE - ESCD_DATA_SIZE bytes allowed)
ehci_legacy byte ; 0 = enumerate ehci devices, 1 = enumerate all hs devices as fs on companion controllers
num_lock byte ; 0 = leave the num lock off, 1 = turn on num_lock at boot time
boot_delay byte ; number of seconds to wait for a F12 press before boot (0 means no delay, 3 = default)
ahci_legacy byte ; 0 = enumerate ahci devices, 1 = enumerate all capable ahci devices as edi devices
; floppy boot signature check (cmos item as well) ???
; last 16-bits is the crc
ESCD_DATA ends
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; was the ESCD read from the flash memory?
; if not, clear it to initialize it
; on entry:
; nothing
; on return
; nothing
; destroys none
bios_escd_init proc near uses ax bx cx ds es
mov ax,BIOS_BASE2
mov ds,ax
mov ax,EBDA_SEG
mov es,ax
; if the data was read from the flash memory,
; the ESCD header will be present
cmp dword [0xC000 + ESCD_DATA->signature],"ACFG"
je short bios_escd_init_done
; if it was not read, we need to clear it out
; and create default values
xor al,al
mov bx,0xC000
mov cx,0x2000
@@: mov [bx],al
inc bx
loop @b
mov bx,0xC000
mov word [bx+ESCD_DATA->size],12
mov dword [bx+ESCD_DATA->signature],"ACFG"
;mov byte [bx+ESCD_DATA->minor_ver],0
mov byte [bx+ESCD_DATA->major_ver],2
;mov byte [bx+ESCD_DATA->board_cnt],0
;mov byte [bx+ESCD_DATA->ehci_legacy],0
mov byte [bx+ESCD_DATA->num_lock],1
mov byte [bx+ESCD_DATA->boot_delay],3
;mov byte [bx+ESCD_DATA->ahci_legacy],0
; mark it as dirty
mov byte es:[EBDA_DATA->escd_dirty],1
bios_escd_init_done:
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; now per the escd data, initialize a few items
; ds:bx -> BIOS_BASE2:ESCD
mov bx,0xC000
; es now set to 0x0040
mov ax,0x0040
mov es,ax
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; make sure all LEDs are off, and corresponding states are set
; (may set the num-lock state if the user has set this above)
mov al,es:[0x0017]
and al,00001111b
cmp byte [bx+ESCD_DATA->num_lock],0
je short @f
or al,00100000b
@@: mov es:[0x0017],al
; calling any keyboard service (int 16h) will set/clear the
; states and LEDs for us
mov ah,02h ; get the status
int 16h
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; next item...
ret
bios_escd_init endp
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; read a value from the escd
; on entry:
; bx = offset within escd to read from
; cx = length of value to write (in bytes)
; on return
; eax = value read (al, ax, or eax)
; destroys none
bios_read_escd proc near uses bx ds
mov ax,BIOS_BASE2
mov ds,ax
cmp bx,0x2000
jae short bios_read_escd_done
add bx,offset escd
xor eax,eax
@@: shl eax,8
mov al,[bx]
inc bx
loop @b
bios_read_escd_done:
ret
bios_read_escd endp
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; write a value to the escd
; use this routine to write to the escd instead of directly writing
; to that memory since this will mark it as dirty.
; on entry:
; eax = value to write (al, ax, or eax)
; bx = offset within escd to write it to
; cx = length of value to write (in bytes)
; on return
; nothing
; destroys none
bios_write_escd proc near uses bx cx dx es ds
mov dx,EBDA_SEG
mov es,dx
mov dx,BIOS_BASE2
mov ds,dx
cmp bx,0x2000
jae short bios_write_escd_done
add bx,offset escd
@@: mov [bx],al
inc bx
shr eax,8
loop @b
mov byte es:[EBDA_DATA->escd_dirty],1
bios_write_escd_done:
ret
bios_write_escd endp
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; calculate and update the crc of the ESCD
; on entry:
; nothing
; on return
; nothing
; destroys none
bios_escd_crc proc near uses ax cx dx si ds
mov ax,BIOS_BASE2
mov ds,ax
mov si,offset escd
xor ah,ah
cwd
mov cx,(ESCD_DATA_TOT_SIZE - sizeof(word))
cld
@@: lodsb
add dx,ax
loop @b
mov [si],dx
ret
bios_escd_crc endp
; =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
; write the escd back to flash rom
; (* is a far procedure *)
; on entry:
; nothing
; on return
; nothing
; destroys none
bios_commit_escd proc far uses all es ds
mov ax,EBDA_SEG
mov es,ax
mov ax,BIOS_BASE2
mov ds,ax
cmp byte es:[EBDA_DATA->escd_dirty],0
je short bios_commit_escd_done
; recalculate the file crc
call bios_escd_crc
; did we find the i440x pci to isa bridge?
mov bx,es:[EBDA_DATA->i440_pciisa]
or bx,bx
jz short bios_commit_escd_done
; activate the BIOS eeprom (set bit 2 in register 0x4E)
mov ax,0xB108
mov di,0x4E
int 1Ah
or cl,0x4
mov ax,0xB10B
int 1Ah
; erase the area from 0x000FC000 to 0x000FCFFFF
mov byte [0xC000],FLASH_ERASE_SETUP
mov byte [0xC000],FLASH_ERASE
; copy the area from 0x000FC000 to 0x000FCFFF to the chip
mov cx,0x1000
mov bx,0xC000
@@: mov al,[bx]
mov byte [0xC000],FLASH_PROG_SETUP
mov [bx],al
inc bx
loop @b
; erase the area from 0x000FD000 to 0x000FDFFF
mov byte [0xD000],FLASH_ERASE_SETUP
mov byte [0xD000],FLASH_ERASE
; copy the area from 0x000FD000 to 0x000FDFFF to the chip
mov cx,0x1000
;mov bx,0xD000
@@: mov al,[bx]
mov byte [0xD000],FLASH_PROG_SETUP
mov [bx],al
inc bx
loop @b
; deactivate the BIOS eeprom (clear bit 2 in register 0x4E)
mov ax,0xB108
mov di,0x4E
int 1Ah
and cl,(~0x4)
mov ax,0xB10B
int 1Ah
mov byte es:[EBDA_DATA->escd_dirty],0
bios_commit_escd_done:
retf
bios_commit_escd endp
.end