1 ; Copyright (C) 1997 Markus Gutschke <gutschk@uni-muenster.de>
3 ; This program is free software; you can redistribute it and/or modify
4 ; it under the terms of the GNU General Public License as published by
5 ; the Free Software Foundation; either version 2 of the License, or
8 ; This program is distributed in the hope that it will be useful,
9 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
10 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 ; GNU General Public License for more details.
13 ; You should have received a copy of the GNU General Public License
14 ; along with this program; if not, write to the Free Software
15 ; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 ; Prepend this image file to an arbitrary ROM image. The resulting binary
18 ; can be loaded from any BOOT-Prom that supports the "nbi" file format.
19 ; When started, the image will reprogram the flash EPROM on the FlashCard
20 ; ISA card. The flash EPROM has to be an AMD 29F010, and the programming
21 ; algorithm is the same as that suggested by AMD in the appropriate data
25 #define SEGLOW
0xC800 /* lower range for EPROM
segment */
26 #define SEGHIGH
0xE800 /* upper range for EPROM
segment */
27 #define AMD_ID
0x2001 /* flash EPROM ID
, only support AMD
*/
28 #define ERASE1_CMD
0x80 /* first cmd for erasing full chip
*/
29 #define ERASE2_CMD
0x10 /* second cmd for erasing full chip
*/
30 #define READID_CMD
0x90 /* cmd to read chip ID
*/
31 #define PROG_CMD
0xA0 /* cmd to program a
byte */
32 #define RESET_CMD
0xF0 /* cmd to reset chip state machine
*/
34 ;----------------------------------------------------------------------------\f
43 mov ax,magic
; verify that we have been loaded by
44 cmp ax,#
0xE4E4 ; boot prom
46 jmpi
0x200,0x0FE0 ; adjust code segment
47 lderr: mov si,#loaderr
50 lodsb ; loop over all characters of
54 int 0x16 ; wait for keypress
55 jmpi
0x0000,0xFFFF ; reboot!
56 lderrnx:mov ah,#
0x0E ; print it
62 loaderr:.ascii
"The flash EPROM utility has to be loaded from a BOOT-Prom"
64 .ascii
"that knows about the 'nbi' file format!"
66 .ascii
"Reboot to proceed..."
72 !----------------------------------------------------------------------------\f
76 mov ax,romdata
; verify that there is an Prom image
77 cmp ax,#
0xAA55 ; attached to the utility
80 or al,al ; non-zero size is required
82 resmag: mov si,#badmagic
; print error message
85 int 0x16 ; wait for keypress
86 jmpi
0x0000,0xFFFF ; reboot!
87 magicok:mov di,#clrline1
88 mov si,#welcome
; print welcome message
91 mov cl,#
0xC ; expect 4 nibbles input data
94 cmp al,#
0x8 ; <Backspace>
96 or bx,bx ; there has to be at least one input ch
98 mov si,#delchar
; wipe out char from screen
100 add cl,#
4 ; compute bitmask for removing input
110 inpnobs:cmp al,#
0x0D ; <Return>
112 or bx,bx ; zero input -> autoprobing
114 cmp cl,#
-4 ; otherwise there have to be 4 nibbles
116 inperr: mov al,#
7 ; ring the console bell
118 inpnocr:cmp al,#
0x15 ; <CTRL-U>
121 call prnstr
; clear entire input and restart
123 inpnokl:cmp cl,#
-4 ; cannot input more than 4 nibbles
128 or bx,bx ; leading '0' is not allowed
130 inpdig: cmp al,#
0x39 ; '9'
134 inpnum: xor ah,ah ; compute new input value
137 test ax,#
0x1FF ; test for 8kB boundary
139 cmp ax,#SEGHIGH
; input has to be below E800
141 cmp ax,#SEGLOW
; and above/equal C800
143 cmp cl,#
0xC ; if there is just one nibble, yet,
144 jnz inperr
; then the lower limit ix C000
147 inpok: mov bx,ax ; adjust bitmask
150 inpecho:call prnchr
; output new character
152 inpnodg:and al,#
0xDF ; lower case -> upper case
160 inpdone:or bx,bx ; zero -> autoprobing
165 mov bx,#SEGHIGH
; scan from E800 to C800
166 autoprb:sub bx,#
0x0200 ; stepping down in 8kB increments
173 nofnd: mov di,#clrline2
174 jmp near inpnew
; failure -> ask user for new input
176 test bx,#
0x07FF ; EPROM might have to be aligned to
177 jz noalign
; 32kB boundary
179 cmp ax,#AMD_ID
; check for AMDs id
183 and bx,#
0xF800 ; enforce alignment of hardware addr
184 noalign:call readid
; check for AMDs id
187 mov si,#nofndmsg
; could not find any EPROM at speci-
188 call prnstr
; fied location --- even tried
189 mov si,#basemsg
; aligning to 32kB boundary
190 jmp nofnd
; failure -> ask user for new input
191 prbfnd: mov si,#fndmsg
192 call prnstr
; we found a flash EPROM
197 call erase
; erase old contents
199 mov si,#failresmsg
; failure -> reboot machine
201 ersdone:mov si,#prg1msg
; tell user that we are about
202 call prnstr
; to program the new data into
203 mov ax,di ; the specified range
224 mov dh,romdata
+2 ; number of 512 byte blocks
227 add ax,#romdata
>>4 ; adjust segment descriptor, so that
228 mov ds,ax ; we can handle images which are
229 prgloop:mov cx,#
0x200 ; larger than 64kB
232 call program
; program 512 data bytes
233 jc prgerr
; check error condition
235 add ax,#
0x20 ; increment segment descriptors
238 dec dh ; decrement counter
241 mov si,#donemsg
; success -> reboot
245 prgerr: pop ds ; failure -> reboot
250 ;----------------------------------------------------------------------------\f
252 ; READID -- read EPROM id number, base address is passed in BX
255 ; changes: AX, DL, ES
257 readid: mov dl,#RESET_CMD
; reset chip
260 call sendop
; send READID command
263 mov ax,0x00 ; read manufacturer ID
265 jmp sendop
; reset chip
268 ;----------------------------------------------------------------------------\f
270 ; ERASE -- erase entire EPROM, base address is passed in BX
273 ; changes: AL, CX, DL, ES, CF
275 erase: mov dl,#ERASE1_CMD
276 call sendop
; send ERASE1 command
278 call sendop
; send ERASE2 command
283 call waitop
; wait until operation finished
287 call sendop
; reset chip
292 ;----------------------------------------------------------------------------\f
294 ; PROGRAM -- write data block at DS:SI of length CX into EPROM at DI:BP
297 ; changes: AX, CX, DL, BP, ES, CF
299 program:mov dl,#PROG_CMD
300 call sendop
; send programming command
301 lodsb ; get next byte from buffer
304 mov byte ptr [bp],al ; write next byte into flash EPROM
305 call waitop
; wait until programming operation is
306 jc progdn
; completed
308 loop program
; continue with next byte
309 clc ; return without error
313 ;----------------------------------------------------------------------------\f
315 ; SENDOP -- send command in DL to EPROM, base address is passed in BX
322 mov byte ptr 0x5555,#
0xAA ; write magic data bytes into
323 jcxz so1
; magic locations. This unlocks
324 so1: jcxz so2
; the flash EPROM. N.B. that the
325 so2: seg es ; magic locations are mirrored
326 mov byte ptr 0x2AAA,#
0x55 ; every 32kB; the hardware address
327 jcxz so3
; might have to be adjusted to a
328 so3: jcxz so4
; 32kB boundary
330 mov byte ptr 0x5555,dl
334 ;----------------------------------------------------------------------------\f
336 ; WAITOP -- wait for command to complete, address is passed in DI:BP
339 ; for details on the programming algorithm, c.f. http://www.amd.com
341 ; changes: AX, DL, ES, CF
343 waitop: and al,#
0x80 ; monitor bit 7
345 wait1: seg es ; read contents of EPROM cell that is
346 mov ah,byte ptr [bp] ; being programmed
349 cmp al,ah ; bit 7 indicates sucess
351 test dl,#
0x20 ; bit 5 indicates timeout/error
352 jz wait1
; otherwise wait for cmd to complete
354 mov ah,byte ptr [bp] ; check error condition once again,
355 and ah,#
0x80 ; because bits 7 and 5 can change
356 cmp al,ah ; simultaneously
363 ;----------------------------------------------------------------------------\f
365 ; PRNSTR -- prints a string in DS:SI onto the console
372 prns1: lodsb ; loop over all characters of
375 call prnchr
; print character
381 ;----------------------------------------------------------------------------\f
383 ; PRNWRD, PRNBYT, PRNNIB, PRNCHR -- prints hexadezimal values, or ASCII chars
384 ; ====== ====== ====== ======
390 call prnbyt
; print the upper byte
393 shr al,1 ; prepare upper nibble
397 call prnnib
; print it
399 prnnib: and al,#
0x0F ; prepare lower nibble
401 cmp al,#
0x39 ; convert it into hex
405 mov ah,#
0x0E ; print it
413 ;----------------------------------------------------------------------------\f
415 magic: .
byte 0xE4,0xE4
417 badmagic:.
byte 0xa,0xd
418 .ascii
"There does not appear to be a ROM image attached to the"
419 .ascii
"flash EPROM utility;"
421 resetmsg:.ascii
"Reboot to proceed..."
424 welcome:.
byte 0xa,0xd
425 .ascii
"Flash EPROM programming utility V1.0"
427 .ascii
"Copyright (c) 1997 by M. Gutschke <gutschk@uni-muenster.de>"
429 .ascii
"==========================================================="
431 prompt: .
byte 0xa,0xd
432 .ascii
"Enter base address for AMD29F010 flash EPROM on FlashCard or"
434 .ascii
"press <RETURN> to start autoprobing; the base address has"
437 .ascii
"to be in the range C800..E600: "
439 .
byte 0x8,0x8,0x8,0x8
442 delchar:.
byte 0x8,0x20,0x8
445 automsg:.ascii
"autoprobing... "
448 failmsg:.ascii
"failed!"
451 .ascii
"Enter base address: "
453 .
byte 0x8,0x8,0x8,0x8
456 fndmsg: .
byte 0xa,0xd
457 .ascii
"Found flash EPROM at: "
460 alignmsg:.
byte 0xa,0xd
461 .ascii
"FlashCard requires the hardware address to be aligned to a"
463 .ascii
"32kB boundary; automatically adjusting..."
466 nofndmsg:.
byte 0xa,0xd
467 .ascii
"No AMD29F010 flash EPROM found"
470 ersmsg: .
byte 0xa,0xd
471 .ascii
"Erasing old contents... "
474 prg1msg:.ascii
"done"
476 .ascii
"Programming from "
479 prg2msg:.ascii
":0000 to "
482 donemsg:.ascii
"done!"
492 ;----------------------------------------------------------------------------\f