You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

flashimg.asm 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. ; Copyright (C) 1997 Markus Gutschke <gutschk@uni-muenster.de>
  2. ;
  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
  6. ; any later version.
  7. ;
  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.
  12. ;
  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.
  16. ; Prepend this image file to an arbitrary ROM image. The resulting binary
  17. ; can be loaded from any BOOT-Prom that supports the "nbi" file format.
  18. ; When started, the image will reprogram the flash EPROM on the FlashCard
  19. ; ISA card. The flash EPROM has to be an AMD 29F010, and the programming
  20. ; algorithm is the same as that suggested by AMD in the appropriate data
  21. ; sheets.
  22. #define SEGLOW 0xC800 /* lower range for EPROM segment */
  23. #define SEGHIGH 0xE800 /* upper range for EPROM segment */
  24. #define AMD_ID 0x2001 /* flash EPROM ID, only support AMD */
  25. #define ERASE1_CMD 0x80 /* first cmd for erasing full chip */
  26. #define ERASE2_CMD 0x10 /* second cmd for erasing full chip */
  27. #define READID_CMD 0x90 /* cmd to read chip ID */
  28. #define PROG_CMD 0xA0 /* cmd to program a byte */
  29. #define RESET_CMD 0xF0 /* cmd to reset chip state machine */
  30. ;----------------------------------------------------------------------------
  31. .text
  32. .org 0
  33. ; .globl _main
  34. _main: mov ax,#0x0FE0
  35. mov ds,ax
  36. mov ax,magic ; verify that we have been loaded by
  37. cmp ax,#0xE4E4 ; boot prom
  38. jnz lderr
  39. jmpi 0x200,0x0FE0 ; adjust code segment
  40. lderr: mov si,#loaderr
  41. cld
  42. lderrlp:seg cs
  43. lodsb ; loop over all characters of
  44. or al,al ; string
  45. jnz lderrnx
  46. xor ah,ah
  47. int 0x16 ; wait for keypress
  48. jmpi 0x0000,0xFFFF ; reboot!
  49. lderrnx:mov ah,#0x0E ; print it
  50. mov bl,#0x07
  51. xor bh,bh
  52. int 0x10
  53. jmp lderrlp
  54. loaderr:.ascii "The flash EPROM utility has to be loaded from a BOOT-Prom"
  55. .byte 0xa,0xd
  56. .ascii "that knows about the 'nbi' file format!"
  57. .byte 0xa,0xd
  58. .ascii "Reboot to proceed..."
  59. .byte 0
  60. .org 510
  61. .byte 0x55,0xAA
  62. !----------------------------------------------------------------------------
  63. start: mov ax,cs
  64. mov ds,ax
  65. mov ax,romdata ; verify that there is an Prom image
  66. cmp ax,#0xAA55 ; attached to the utility
  67. jnz resmag
  68. mov al,romdata+2
  69. or al,al ; non-zero size is required
  70. jnz magicok
  71. resmag: mov si,#badmagic ; print error message
  72. reset: call prnstr
  73. xor ah,ah
  74. int 0x16 ; wait for keypress
  75. jmpi 0x0000,0xFFFF ; reboot!
  76. magicok:mov di,#clrline1
  77. mov si,#welcome ; print welcome message
  78. inpnew: call prnstr
  79. inprest:xor bx,bx
  80. mov cl,#0xC ; expect 4 nibbles input data
  81. inploop:xor ah,ah
  82. int 0x16
  83. cmp al,#0x8 ; <Backspace>
  84. jnz inpnobs
  85. or bx,bx ; there has to be at least one input ch
  86. jz inperr
  87. mov si,#delchar ; wipe out char from screen
  88. call prnstr
  89. add cl,#4 ; compute bitmask for removing input
  90. mov ch,cl
  91. mov cl,#0xC
  92. sub cl,ch
  93. mov ax,#0xFFFF
  94. shr ax,cl
  95. not ax
  96. and bx,ax
  97. mov cl,ch
  98. inploop1:jmp inploop
  99. inpnobs:cmp al,#0x0D ; <Return>
  100. jnz inpnocr
  101. or bx,bx ; zero input -> autoprobing
  102. jz inpdone
  103. cmp cl,#-4 ; otherwise there have to be 4 nibbles
  104. jz inpdone
  105. inperr: mov al,#7 ; ring the console bell
  106. jmp inpecho
  107. inpnocr:cmp al,#0x15 ; <CTRL-U>
  108. jnz inpnokl
  109. mov si,di
  110. call prnstr ; clear entire input and restart
  111. jmp inprest
  112. inpnokl:cmp cl,#-4 ; cannot input more than 4 nibbles
  113. jz inperr
  114. cmp al,#0x30 ; '0'
  115. jb inperr
  116. ja inpdig
  117. or bx,bx ; leading '0' is not allowed
  118. jz inperr
  119. inpdig: cmp al,#0x39 ; '9'
  120. ja inpnodg
  121. mov ch,al
  122. sub al,#0x30
  123. inpnum: xor ah,ah ; compute new input value
  124. shl ax,cl
  125. add ax,bx
  126. test ax,#0x1FF ; test for 8kB boundary
  127. jnz inperr
  128. cmp ax,#SEGHIGH ; input has to be below E800
  129. jae inperr
  130. cmp ax,#SEGLOW ; and above/equal C800
  131. jae inpok
  132. cmp cl,#0xC ; if there is just one nibble, yet,
  133. jnz inperr ; then the lower limit ix C000
  134. cmp ax,#0xC000
  135. jb inperr
  136. inpok: mov bx,ax ; adjust bitmask
  137. sub cl,#4
  138. mov al,ch
  139. inpecho:call prnchr ; output new character
  140. jmp inploop1
  141. inpnodg:and al,#0xDF ; lower case -> upper case
  142. cmp al,#0x41 ; 'A'
  143. jb inperr
  144. cmp al,#0x46 ; 'F'
  145. ja inperr
  146. mov ch,al
  147. sub al,#0x37
  148. jmp inpnum
  149. inpdone:or bx,bx ; zero -> autoprobing
  150. jnz probe
  151. mov si,#automsg
  152. call prnstr
  153. mov cx,#0x10
  154. mov bx,#SEGHIGH ; scan from E800 to C800
  155. autoprb:sub bx,#0x0200 ; stepping down in 8kB increments
  156. mov di,bx
  157. call readid
  158. cmp ax,#AMD_ID
  159. jz prbfnd
  160. loop autoprb
  161. mov si,#failmsg
  162. nofnd: mov di,#clrline2
  163. jmp near inpnew ; failure -> ask user for new input
  164. probe: mov di,bx
  165. test bx,#0x07FF ; EPROM might have to be aligned to
  166. jz noalign ; 32kB boundary
  167. call readid
  168. cmp ax,#AMD_ID ; check for AMDs id
  169. jz prbfnd
  170. mov si,#alignmsg
  171. call prnstr
  172. and bx,#0xF800 ; enforce alignment of hardware addr
  173. noalign:call readid ; check for AMDs id
  174. cmp ax,#AMD_ID
  175. jz prbfnd
  176. mov si,#nofndmsg ; could not find any EPROM at speci-
  177. call prnstr ; fied location --- even tried
  178. mov si,#basemsg ; aligning to 32kB boundary
  179. jmp nofnd ; failure -> ask user for new input
  180. prbfnd: mov si,#fndmsg
  181. call prnstr ; we found a flash EPROM
  182. mov ax,bx
  183. call prnwrd
  184. mov si,#ersmsg
  185. call prnstr
  186. call erase ; erase old contents
  187. jnc ersdone
  188. mov si,#failresmsg ; failure -> reboot machine
  189. jmp near reset
  190. ersdone:mov si,#prg1msg ; tell user that we are about
  191. call prnstr ; to program the new data into
  192. mov ax,di ; the specified range
  193. call prnwrd
  194. mov si,#prg2msg
  195. call prnstr
  196. xor dh,dh
  197. mov dl,romdata+2
  198. shl dx,#1
  199. mov ah,dh
  200. mov cl,#4
  201. shl ah,cl
  202. xor al,al
  203. add ax,di
  204. call prnwrd
  205. mov al,#0x3A ; ':'
  206. call prnchr
  207. mov ah,dl
  208. xor al,al
  209. dec ax
  210. call prnwrd
  211. mov al,#0x20
  212. call prnchr
  213. mov dh,romdata+2 ; number of 512 byte blocks
  214. push ds
  215. mov ax,ds
  216. add ax,#romdata>>4 ; adjust segment descriptor, so that
  217. mov ds,ax ; we can handle images which are
  218. prgloop:mov cx,#0x200 ; larger than 64kB
  219. xor si,si
  220. xor bp,bp
  221. call program ; program 512 data bytes
  222. jc prgerr ; check error condition
  223. mov ax,ds
  224. add ax,#0x20 ; increment segment descriptors
  225. mov ds,ax
  226. add di,#0x20
  227. dec dh ; decrement counter
  228. jnz prgloop
  229. pop ds
  230. mov si,#donemsg ; success -> reboot
  231. prgdone:call prnstr
  232. mov si,#resetmsg
  233. jmp near reset
  234. prgerr: pop ds ; failure -> reboot
  235. mov si,#failresmsg
  236. jmp prgdone
  237. ;----------------------------------------------------------------------------
  238. ; READID -- read EPROM id number, base address is passed in BX
  239. ; ======
  240. ;
  241. ; changes: AX, DL, ES
  242. readid: mov dl,#RESET_CMD ; reset chip
  243. call sendop
  244. mov dl,#READID_CMD
  245. call sendop ; send READID command
  246. mov es,bx
  247. seg es
  248. mov ax,0x00 ; read manufacturer ID
  249. mov dl,#RESET_CMD
  250. jmp sendop ; reset chip
  251. ;----------------------------------------------------------------------------
  252. ; ERASE -- erase entire EPROM, base address is passed in BX
  253. ; =====
  254. ;
  255. ; changes: AL, CX, DL, ES, CF
  256. erase: mov dl,#ERASE1_CMD
  257. call sendop ; send ERASE1 command
  258. mov dl,#ERASE2_CMD
  259. call sendop ; send ERASE2 command
  260. xor bp,bp
  261. mov al,#0xFF
  262. push di
  263. mov di,bx
  264. call waitop ; wait until operation finished
  265. pop di
  266. jnc erfail
  267. mov dl,#RESET_CMD
  268. call sendop ; reset chip
  269. stc
  270. erfail: ret
  271. ;----------------------------------------------------------------------------
  272. ; PROGRAM -- write data block at DS:SI of length CX into EPROM at DI:BP
  273. ; =======
  274. ;
  275. ; changes: AX, CX, DL, BP, ES, CF
  276. program:mov dl,#PROG_CMD
  277. call sendop ; send programming command
  278. lodsb ; get next byte from buffer
  279. mov es,di
  280. seg es
  281. mov byte ptr [bp],al ; write next byte into flash EPROM
  282. call waitop ; wait until programming operation is
  283. jc progdn ; completed
  284. inc bp
  285. loop program ; continue with next byte
  286. clc ; return without error
  287. progdn: ret
  288. ;----------------------------------------------------------------------------
  289. ; SENDOP -- send command in DL to EPROM, base address is passed in BX
  290. ; ======
  291. ;
  292. ; changes: ES
  293. sendop: mov es,bx
  294. seg es
  295. mov byte ptr 0x5555,#0xAA ; write magic data bytes into
  296. jcxz so1 ; magic locations. This unlocks
  297. so1: jcxz so2 ; the flash EPROM. N.B. that the
  298. so2: seg es ; magic locations are mirrored
  299. mov byte ptr 0x2AAA,#0x55 ; every 32kB; the hardware address
  300. jcxz so3 ; might have to be adjusted to a
  301. so3: jcxz so4 ; 32kB boundary
  302. so4: seg es
  303. mov byte ptr 0x5555,dl
  304. ret
  305. ;----------------------------------------------------------------------------
  306. ; WAITOP -- wait for command to complete, address is passed in DI:BP
  307. ; ======
  308. ;
  309. ; for details on the programming algorithm, c.f. http://www.amd.com
  310. ;
  311. ; changes: AX, DL, ES, CF
  312. waitop: and al,#0x80 ; monitor bit 7
  313. mov es,di
  314. wait1: seg es ; read contents of EPROM cell that is
  315. mov ah,byte ptr [bp] ; being programmed
  316. mov dl,ah
  317. and ah,#0x80
  318. cmp al,ah ; bit 7 indicates sucess
  319. je waitok
  320. test dl,#0x20 ; bit 5 indicates timeout/error
  321. jz wait1 ; otherwise wait for cmd to complete
  322. seg es
  323. mov ah,byte ptr [bp] ; check error condition once again,
  324. and ah,#0x80 ; because bits 7 and 5 can change
  325. cmp al,ah ; simultaneously
  326. je waitok
  327. stc
  328. ret
  329. waitok: clc
  330. ret
  331. ;----------------------------------------------------------------------------
  332. ; PRNSTR -- prints a string in DS:SI onto the console
  333. ; ======
  334. ;
  335. ; changes: AL
  336. prnstr: push si
  337. cld
  338. prns1: lodsb ; loop over all characters of
  339. or al,al ; string
  340. jz prns2
  341. call prnchr ; print character
  342. jmp prns1
  343. prns2: pop si
  344. ret
  345. ;----------------------------------------------------------------------------
  346. ; PRNWRD, PRNBYT, PRNNIB, PRNCHR -- prints hexadezimal values, or ASCII chars
  347. ; ====== ====== ====== ======
  348. ;
  349. ; changes: AX
  350. prnwrd: push ax
  351. mov al,ah
  352. call prnbyt ; print the upper byte
  353. pop ax
  354. prnbyt: push ax
  355. shr al,1 ; prepare upper nibble
  356. shr al,1
  357. shr al,1
  358. shr al,1
  359. call prnnib ; print it
  360. pop ax
  361. prnnib: and al,#0x0F ; prepare lower nibble
  362. add al,#0x30
  363. cmp al,#0x39 ; convert it into hex
  364. jle prnchr
  365. add al,#7
  366. prnchr: push bx
  367. mov ah,#0x0E ; print it
  368. mov bl,#0x07
  369. xor bh,bh
  370. int 0x10
  371. pop bx
  372. ret
  373. ;----------------------------------------------------------------------------
  374. magic: .byte 0xE4,0xE4
  375. badmagic:.byte 0xa,0xd
  376. .ascii "There does not appear to be a ROM image attached to the"
  377. .ascii "flash EPROM utility;"
  378. .byte 0xa,0xd
  379. resetmsg:.ascii "Reboot to proceed..."
  380. .byte 0
  381. welcome:.byte 0xa,0xd
  382. .ascii "Flash EPROM programming utility V1.0"
  383. .byte 0xa,0xd
  384. .ascii "Copyright (c) 1997 by M. Gutschke <gutschk@uni-muenster.de>"
  385. .byte 0xa,0xd
  386. .ascii "==========================================================="
  387. .byte 0xa,0xd
  388. prompt: .byte 0xa,0xd
  389. .ascii "Enter base address for AMD29F010 flash EPROM on FlashCard or"
  390. .byte 0xa,0xd
  391. .ascii "press <RETURN> to start autoprobing; the base address has"
  392. .byte 0xa
  393. clrline1:.byte 0xd
  394. .ascii "to be in the range C800..E600: "
  395. .ascii " "
  396. .byte 0x8,0x8,0x8,0x8
  397. .byte 0
  398. delchar:.byte 0x8,0x20,0x8
  399. .byte 0
  400. automsg:.ascii "autoprobing... "
  401. .byte 0
  402. failmsg:.ascii "failed!"
  403. basemsg:.byte 0xa
  404. clrline2:.byte 0xd
  405. .ascii "Enter base address: "
  406. .ascii " "
  407. .byte 0x8,0x8,0x8,0x8
  408. .byte 0
  409. fndmsg: .byte 0xa,0xd
  410. .ascii "Found flash EPROM at: "
  411. .byte 0
  412. alignmsg:.byte 0xa,0xd
  413. .ascii "FlashCard requires the hardware address to be aligned to a"
  414. .byte 0xa,0xd
  415. .ascii "32kB boundary; automatically adjusting..."
  416. .byte 0
  417. nofndmsg:.byte 0xa,0xd
  418. .ascii "No AMD29F010 flash EPROM found"
  419. .byte 0
  420. ersmsg: .byte 0xa,0xd
  421. .ascii "Erasing old contents... "
  422. .byte 0
  423. prg1msg:.ascii "done"
  424. .byte 0xa,0xd
  425. .ascii "Programming from "
  426. .byte 0
  427. prg2msg:.ascii ":0000 to "
  428. .byte 0
  429. donemsg:.ascii "done!"
  430. .byte 0xa,0xd
  431. .byte 0
  432. failresmsg:
  433. .ascii "failed!"
  434. .byte 0xa,0xd
  435. .byte 0
  436. ;----------------------------------------------------------------------------
  437. .align 16
  438. .org *-1
  439. .byte 0x00
  440. romdata: