File: flash.asm

package info (click to toggle)
netboot 0.8.1-4
  • links: PTS
  • area: main
  • in suites: potato
  • size: 2,728 kB
  • ctags: 4,740
  • sloc: ansic: 15,152; asm: 11,623; yacc: 2,248; makefile: 1,110; pascal: 1,108; lex: 748; sh: 233
file content (475 lines) | stat: -rw-r--r-- 11,666 bytes parent folder | download | duplicates (4)
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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
;**************************************************************************
;*
;* FLASH - Program FlashCard flash EPROM
;*
;* Module:  flash.asm
;* Purpose: Program FlashCard flash EPROM
;* Entries: start
;*
;**************************************************************************
;*
;* Copyright (C) 1995-1998 Gero Kuhlmann <gero@gkminix.han.de>
;*
;*  This program is free software; you can redistribute it and/or modify
;*  it under the terms of the GNU General Public License as published by
;*  the Free Software Foundation; either version 2 of the License, or
;*  any later version.
;*
;*  This program is distributed in the hope that it will be useful,
;*  but WITHOUT ANY WARRANTY; without even the implied warranty of
;*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;*  GNU General Public License for more details.
;*
;*  You should have received a copy of the GNU General Public License
;*  along with this program; if not, write to the Free Software
;*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;*
;**************************************************************************
;*

;
;**************************************************************************
;
; The purpose of this program is to program the flash EPROM on the FlashCard
; ISA card. The flash EPROM has to be an AMD 29F010, and the programming
; algorithm is the same as that suggested by AMD in the appropriate data
; sheets.
;
.model	small,pascal
.stack	256				; 256 stack bytes should be sufficient


;
;**************************************************************************
;
; Miscellaneous defines:
;
CMDLINE		equ	00080h		; offset of command line into PSP

BUFSIZE		equ	512		; size of read buffer
FNAMSIZE	equ	64		; maximum size of filename

SEGLOW		equ	0C800h		; lower range for EPROM segment
SEGHIGH		equ	0E800h		; upper range for EPROM segment
SEGMASK		equ	0FE00h		; mask for 8kB boundary

AMD_ID		equ	2001h		; flash EPROM ID, only support AMD

ERASE1_CMD	equ	080h		; first command for erasing full chip
ERASE2_CMD	equ	010h		; second command for erasing full chip
READID_CMD	equ	090h		; command to read chip ID
PROG_CMD	equ	0A0h		; command to program a byte
RESET_CMD	equ	0F0h		; command to reset chip state machine


;
;**************************************************************************
;
; Constant segment:
;
.const

cpymsg		db	'flash - Flash EPROM programming utility',0Dh,0Ah
		db	'Copyright (C) G. Kuhlmann, 1996',0Dh,0Ah
		db	0Dh,0Ah,'$'

segerr		db	'Illegal segment '
		db	'(must be between C800 and E800 on 8kB boundary)'
		db	0Dh,0Ah,'$'

useerr		db	'usage: flash <seg-addr> <file name>'
		db	0Dh,0Ah,'$'

filerr		db	'Cannot open input file'
		db	0Dh,0Ah,'$'

rderr		db	'Cannot read from input file'
		db	0Dh,0Ah,'$'

iderr		db	'Invalid manufacturer ID or no Flash-EPROM installed'
		db	0Dh,0Ah,'$'

prgerr		db	'Timeout while programming or erasing Flash-EPROM'
		db	0Dh,0Ah,'$'

prgmsg		db	'Programming... $'

endmsg		db	'finished'
		db	0Dh,0Ah,'$'


;
;**************************************************************************
;
; Data segment:
;
.data

fseg		dw	0D000h			; flash EPROM segment
handle		dw	0			; data file handle
filename	db	FNAMSIZE dup (0)	; file name buffer
buf		db	BUFSIZE dup (0)		; read buffer


;
;**************************************************************************
;
; Program start
;
.code

	assume	cs:_text
	assume	ds:nothing
	assume	es:nothing

start:	mov	ax,@data
	mov	es,ax
	assume	es:dgroup

; First analyze the command line. The only arguments for this program
; are the EPROM segment address in hex and the data file name.

	mov	si,CMDLINE + 1
	call	skipblank
	cmp	al,0Dh
	je	short start5
	call	gethex			; get hex number
	cmp	bx,SEGLOW		; should be in the range of C800h
	jb	short start2		; and E800h
	cmp	bx,SEGHIGH
	ja	short start2
	test	bx,not SEGMASK		; segment has to be on 8kB boundary
	jz	short start4
start2:	mov	dx,offset segerr
start3:	mov	ax,@data
	mov	ds,ax
start1:	mov	ah,09h			; print error message
	int	21h
	jmp	doend

start4:	mov	es:fseg,bx		; save EPROM segment address
	call	skipblank
	cmp	al,0Dh
	je	short start5
	call	copyfnam		; copy filename
	call	skipblank		; nothing should follow anymore
	cmp	al,0Dh
	je	short start6
start5:	mov	dx,offset useerr	; print usage message
	jmp	short start3

; We now analyzed the whole command line, so the PSP segment in DS is
; no longer needed. Setup all segment registers correctly, and then try
; to open the data file.

start6:	mov	ax,@data
	mov	ds,ax			; set segment registers
	mov	es,ax
	assume	ds:dgroup
	assume	es:dgroup

	mov	dx,offset cpymsg	; print copyright
	mov	ah,09h
	int	21h

	mov	ax,3D00h
	mov	dx,offset filename	; open the data file
	int	21h
	mov	dx,offset filerr
	jc	short error		; print error message if unsuccessful
	mov	handle,ax		; save file handle

; Read the flash EPROM ID to check if there really is an AMD flash EPROM
; where the user says it should be. Then erase the whole chip to allow
; programming lateron.

	call	readid			; read manufacturer ID from chip
	mov	dx,offset iderr
	cmp	bx,AMD_ID		; check for AMD
	jne	short error

	call	erase
	mov	dx,offset prgerr	; erase the whole chip
	jc	short error

; Now read every block from the data file and program it into the flash
; EPROM. Verification of the programmed data is not necessary, as the
; flash EPROM will do that by itself. It will return an unsuccessful
; programming cycle if it's internal verification showed an error.

	mov	dx,offset prgmsg
	mov	ah,09h			; print programming message
	int	21h
	xor	bx,bx
start7:	push	bx
	mov	ax,3F00h
	mov	bx,handle
	mov	cx,BUFSIZE		; read next block from data file
	mov	dx,offset buf
	int	21h
	pop	bx
	mov	dx,offset rderr		; check for read error
	jc	short error
	or	ax,ax			; check for end of file
	jz	short start8
	mov	cx,ax
	call	program			; program the data block into the
	mov	dx,offset prgerr	; flash EPROM and check for a pro-
	jnc	short start7		; gramming error
error:	jmp	start1


start8:	mov	dx,offset endmsg
	mov	ah,09h			; print end-of-programming message
	int	21h
doend:	mov	ax,4C01h		; terminate program
	int	21h
	ret


;
;**************************************************************************
;
; Skip blanks on command line.
; Input:  DS:SI  -  pointer to command line
; Output: DS:SI  -  pointer to first non-blank
;         AL     -  first non-blank character
; Registers changed: AX, SI
;
skipblank	proc	near

	cld
skip1:	lodsb
	cmp	al,' '			; skip blanks
	je	short skip1
	cmp	al,09h			; skip tabs
	je	short skip1
	dec	si			; point SI to first non-blank
	ret

skipblank	endp


;
;**************************************************************************
;
; Return hex number from string pointed to by DS:SI.
; Input:  DS:SI  -  pointer to string
; Output: DS:SI  -  pointer to first character after hex number
;         BX     -  hex number
; Registers changed: AX, BX, CX, SI
;
gethex		proc	near

	xor	bx,bx
geth1:	lodsb
	cmp	al,'0'
	jb	short geth9		; check for valid hex digit
	cmp	al,'9'
	jbe	short geth3
	cmp	al,'A'
	jb	short geth9
	cmp	al,'a'
	jb	short geth2
	sub	al,20h			; convert character to upper case
geth2:	cmp	al,'F'
	ja	short geth9
	sub	al,7
geth3:	sub	al,'0'			; convert character to digit
	and	al,0Fh
	mov	cl,4
	shl	bx,cl			; include digit into result
	or	bl,al
	jmp	short geth1		; get next character

geth9:	dec	si			; point SI to last non-digit
	ret

gethex		endp


;
;**************************************************************************
;
; Copy filename from command line into buffer
; Input:  DS:SI  -  pointer to string
; Output: DS:SI  -  pointer to first character after filename
; Registers changed: AX, CX, SI, DI
;
copyfnam	proc	near

	push	es
	mov	ax,@data
	mov	es,ax
	mov	cx,FNAMSIZE - 1		; don't copy past filename buffer
	mov	di,offset filename	; put address to filename buffer
	cld				; into ES:DI
copyf1:	lodsb
	or	al,al
	jz	short copyf9		; check for valid filename character
	cmp	al,' '
	jbe	short copyf9
	cmp	al,7Fh
	jae	short copyf9
	stosb				; copy character
	loop	short copyf1
copyf9:	xor	al,al
	stosb				; copy terminating null
	dec	si
	pop	es
	ret

copyfnam	endp


;
;**************************************************************************
;
; Read manufacturer ID from Flash-EPROM
; Input:  none
; Output: BX  -  manufacturer ID
; Registers changed: AX, BX
;
readid		proc	near

	mov	al,READID_CMD
	call	sendop			; send READID command
	push	es
	mov	es,fseg
	mov	bx,es:[0000h]		; read manufacturer ID
	pop	es
	mov	al,RESET_CMD
	call	sendop			; reset chip
	ret

readid		endp


;
;**************************************************************************
;
; Erase whole chip
; Input:  none
; Output: carry flag set if error
; Registers changed: AX, BX
;
erase		proc	near

	mov	al,ERASE1_CMD
	call	sendop			; send ERASE1 command
	mov	al,ERASE2_CMD
	call	sendop			; send ERASE2 command
	xor	bx,bx
	mov	al,0FFh
	call	waitop			; wait until operation finished
	jnc	short erase9
	mov	al,RESET_CMD
	call	sendop			; reset chip
	stc
erase9:	ret

erase		endp


;
;**************************************************************************
;
; Program Flash-EPROM with contents in read buffer
; Input:  BX  -  offset to next byte to program
;         CX  -  number of bytes to program
; Output: BX  -  offset to byte after last programmed byte
;         carry flag set if error
; Registers changed: AX, BX, CX, SI
;
program		proc	near

	mov	si,offset buf
prog1:	mov	al,PROG_CMD
	call	sendop			; send programming command
	lodsb				; get next byte from buffer
	push	es
	mov	es,fseg
	mov	es:[bx],al		; write next byte into flash EPROM
	pop	es
	call	waitop			; wait until programming operation is
	jc	short prog9		; completed
	inc	bx
	loop	prog1			; continue with next byte
	clc				; return without error
prog9:	ret

program		endp


;
;**************************************************************************
;
; Send OP code to Flash_EPROM. This involves writing three bytes into the
; flash EPROM at exactly specified locations. See AMD data sheets for
; further information.
; Input:  AL  -  command byte
; Output: none
; Registers changed: none
;
sendop		proc	near

	push	es
	mov	es,fseg
	mov	byte ptr es:[5555h],0AAh
	jcxz	@F
@@:	jcxz	@F
@@:	mov	byte ptr es:[2AAAh],055h
	jcxz	@F
@@:	jcxz	@F
@@:	mov	byte ptr es:[5555h],al
	pop	es
	ret

sendop		endp


;
;**************************************************************************
;
; Wait for the chip to process programming/erase. When programming is in
; progress, the flash EPROM toggles the highest bit, and converts it back
; to it's original value when the programming is done. For a further ex-
; planation of this algorithm see the AMD data sheets.
; Input:  AL  -  programmed byte
;         BX  -  offset to programming location
; Output: carry flag set if error
; Registers changed: AX
;
waitop		proc	near

	push	cx
	and	al,10000000b
	push	es
	mov	es,fseg
wait1:	mov	ah,es:[bx]
	mov	ch,ah
	and	ah,10000000b
	cmp	al,ah
	je	short wait8
	test	ch,00100000b
	jz	short wait1
	mov	ah,es:[bx]
	and	ah,10000000b
	cmp	al,ah
	je	short wait8
	stc
	jmp	short wait9
wait8:	clc
wait9:	pop	es
	pop	cx
	ret

waitop		endp


;
;**************************************************************************
;

	end	start