📄 flashimg.asm
字号:
; Copyright (C) 1997 Markus Gutschke <gutschk@uni-muenster.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.; Prepend this image file to an arbitrary ROM image. The resulting binary; can be loaded from any BOOT-Prom that supports the "nbi" file format.; When started, the image will reprogram 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.#define SEGLOW 0xC800 /* lower range for EPROM segment */#define SEGHIGH 0xE800 /* upper range for EPROM segment */#define AMD_ID 0x2001 /* flash EPROM ID, only support AMD */#define ERASE1_CMD 0x80 /* first cmd for erasing full chip */#define ERASE2_CMD 0x10 /* second cmd for erasing full chip */#define READID_CMD 0x90 /* cmd to read chip ID */#define PROG_CMD 0xA0 /* cmd to program a byte */#define RESET_CMD 0xF0 /* cmd to reset chip state machine */;---------------------------------------------------------------------------- .text .org 0; .globl _main_main: mov ax,#0x0FE0 mov ds,ax mov ax,magic ; verify that we have been loaded by cmp ax,#0xE4E4 ; boot prom jnz lderr jmpi 0x200,0x0FE0 ; adjust code segmentlderr: mov si,#loaderr cldlderrlp:seg cs lodsb ; loop over all characters of or al,al ; string jnz lderrnx xor ah,ah int 0x16 ; wait for keypress jmpi 0x0000,0xFFFF ; reboot!lderrnx:mov ah,#0x0E ; print it mov bl,#0x07 xor bh,bh int 0x10 jmp lderrlploaderr:.ascii "The flash EPROM utility has to be loaded from a BOOT-Prom" .byte 0xa,0xd .ascii "that knows about the 'nbi' file format!" .byte 0xa,0xd .ascii "Reboot to proceed..." .byte 0 .org 510 .byte 0x55,0xAA!----------------------------------------------------------------------------start: mov ax,cs mov ds,ax mov ax,romdata ; verify that there is an Prom image cmp ax,#0xAA55 ; attached to the utility jnz resmag mov al,romdata+2 or al,al ; non-zero size is required jnz magicokresmag: mov si,#badmagic ; print error messagereset: call prnstr xor ah,ah int 0x16 ; wait for keypress jmpi 0x0000,0xFFFF ; reboot!magicok:mov di,#clrline1 mov si,#welcome ; print welcome messageinpnew: call prnstrinprest:xor bx,bx mov cl,#0xC ; expect 4 nibbles input datainploop:xor ah,ah int 0x16 cmp al,#0x8 ; <Backspace> jnz inpnobs or bx,bx ; there has to be at least one input ch jz inperr mov si,#delchar ; wipe out char from screen call prnstr add cl,#4 ; compute bitmask for removing input mov ch,cl mov cl,#0xC sub cl,ch mov ax,#0xFFFF shr ax,cl not ax and bx,ax mov cl,chinploop1:jmp inploopinpnobs:cmp al,#0x0D ; <Return> jnz inpnocr or bx,bx ; zero input -> autoprobing jz inpdone cmp cl,#-4 ; otherwise there have to be 4 nibbles jz inpdoneinperr: mov al,#7 ; ring the console bell jmp inpechoinpnocr:cmp al,#0x15 ; <CTRL-U> jnz inpnokl mov si,di call prnstr ; clear entire input and restart jmp inprestinpnokl:cmp cl,#-4 ; cannot input more than 4 nibbles jz inperr cmp al,#0x30 ; '0' jb inperr ja inpdig or bx,bx ; leading '0' is not allowed jz inperrinpdig: cmp al,#0x39 ; '9' ja inpnodg mov ch,al sub al,#0x30inpnum: xor ah,ah ; compute new input value shl ax,cl add ax,bx test ax,#0x1FF ; test for 8kB boundary jnz inperr cmp ax,#SEGHIGH ; input has to be below E800 jae inperr cmp ax,#SEGLOW ; and above/equal C800 jae inpok cmp cl,#0xC ; if there is just one nibble, yet, jnz inperr ; then the lower limit ix C000 cmp ax,#0xC000 jb inperrinpok: mov bx,ax ; adjust bitmask sub cl,#4 mov al,chinpecho:call prnchr ; output new character jmp inploop1inpnodg:and al,#0xDF ; lower case -> upper case cmp al,#0x41 ; 'A' jb inperr cmp al,#0x46 ; 'F' ja inperr mov ch,al sub al,#0x37 jmp inpnuminpdone:or bx,bx ; zero -> autoprobing jnz probe mov si,#automsg call prnstr mov cx,#0x10 mov bx,#SEGHIGH ; scan from E800 to C800autoprb:sub bx,#0x0200 ; stepping down in 8kB increments mov di,bx call readid cmp ax,#AMD_ID jz prbfnd loop autoprb mov si,#failmsgnofnd: mov di,#clrline2 jmp near inpnew ; failure -> ask user for new inputprobe: mov di,bx test bx,#0x07FF ; EPROM might have to be aligned to jz noalign ; 32kB boundary call readid cmp ax,#AMD_ID ; check for AMDs id jz prbfnd mov si,#alignmsg call prnstr and bx,#0xF800 ; enforce alignment of hardware addrnoalign:call readid ; check for AMDs id cmp ax,#AMD_ID jz prbfnd mov si,#nofndmsg ; could not find any EPROM at speci- call prnstr ; fied location --- even tried mov si,#basemsg ; aligning to 32kB boundary jmp nofnd ; failure -> ask user for new inputprbfnd: mov si,#fndmsg call prnstr ; we found a flash EPROM mov ax,bx call prnwrd mov si,#ersmsg call prnstr call erase ; erase old contents jnc ersdone mov si,#failresmsg ; failure -> reboot machine jmp near resetersdone:mov si,#prg1msg ; tell user that we are about call prnstr ; to program the new data into mov ax,di ; the specified range call prnwrd mov si,#prg2msg call prnstr xor dh,dh mov dl,romdata+2 shl dx,#1 mov ah,dh mov cl,#4 shl ah,cl xor al,al add ax,di call prnwrd mov al,#0x3A ; ':' call prnchr mov ah,dl xor al,al dec ax call prnwrd mov al,#0x20 call prnchr mov dh,romdata+2 ; number of 512 byte blocks push ds mov ax,ds add ax,#romdata>>4 ; adjust segment descriptor, so that mov ds,ax ; we can handle images which areprgloop:mov cx,#0x200 ; larger than 64kB xor si,si xor bp,bp call program ; program 512 data bytes jc prgerr ; check error condition mov ax,ds add ax,#0x20 ; increment segment descriptors mov ds,ax add di,#0x20 dec dh ; decrement counter jnz prgloop pop ds mov si,#donemsg ; success -> rebootprgdone:call prnstr mov si,#resetmsg jmp near resetprgerr: pop ds ; failure -> reboot mov si,#failresmsg jmp prgdone;----------------------------------------------------------------------------; READID -- read EPROM id number, base address is passed in BX; ======;; changes: AX, DL, ESreadid: mov dl,#RESET_CMD ; reset chip call sendop mov dl,#READID_CMD call sendop ; send READID command mov es,bx seg es mov ax,0x00 ; read manufacturer ID mov dl,#RESET_CMD jmp sendop ; reset chip;----------------------------------------------------------------------------; ERASE -- erase entire EPROM, base address is passed in BX; =====;; changes: AL, CX, DL, ES, CFerase: mov dl,#ERASE1_CMD call sendop ; send ERASE1 command mov dl,#ERASE2_CMD call sendop ; send ERASE2 command xor bp,bp mov al,#0xFF push di mov di,bx call waitop ; wait until operation finished pop di jnc erfail mov dl,#RESET_CMD call sendop ; reset chip stcerfail: ret;----------------------------------------------------------------------------; PROGRAM -- write data block at DS:SI of length CX into EPROM at DI:BP; =======;; changes: AX, CX, DL, BP, ES, CFprogram:mov dl,#PROG_CMD call sendop ; send programming command lodsb ; get next byte from buffer mov es,di seg es mov byte ptr [bp],al ; write next byte into flash EPROM call waitop ; wait until programming operation is jc progdn ; completed inc bp loop program ; continue with next byte clc ; return without errorprogdn: ret;----------------------------------------------------------------------------; SENDOP -- send command in DL to EPROM, base address is passed in BX; ======;; changes: ESsendop: mov es,bx seg es mov byte ptr 0x5555,#0xAA ; write magic data bytes into jcxz so1 ; magic locations. This unlocksso1: jcxz so2 ; the flash EPROM. N.B. that theso2: seg es ; magic locations are mirrored mov byte ptr 0x2AAA,#0x55 ; every 32kB; the hardware address jcxz so3 ; might have to be adjusted to aso3: jcxz so4 ; 32kB boundaryso4: seg es mov byte ptr 0x5555,dl ret;----------------------------------------------------------------------------; WAITOP -- wait for command to complete, address is passed in DI:BP; ======;; for details on the programming algorithm, c.f. http://www.amd.com;; changes: AX, DL, ES, CFwaitop: and al,#0x80 ; monitor bit 7 mov es,diwait1: seg es ; read contents of EPROM cell that is mov ah,byte ptr [bp] ; being programmed mov dl,ah and ah,#0x80 cmp al,ah ; bit 7 indicates sucess je waitok test dl,#0x20 ; bit 5 indicates timeout/error jz wait1 ; otherwise wait for cmd to complete seg es mov ah,byte ptr [bp] ; check error condition once again, and ah,#0x80 ; because bits 7 and 5 can change cmp al,ah ; simultaneously je waitok stc retwaitok: clc ret;----------------------------------------------------------------------------; PRNSTR -- prints a string in DS:SI onto the console; ======;; changes: ALprnstr: push si cldprns1: lodsb ; loop over all characters of or al,al ; string jz prns2 call prnchr ; print character jmp prns1prns2: pop si ret;----------------------------------------------------------------------------; PRNWRD, PRNBYT, PRNNIB, PRNCHR -- prints hexadezimal values, or ASCII chars; ====== ====== ====== ======;; changes: AXprnwrd: push ax mov al,ah call prnbyt ; print the upper byte pop axprnbyt: push ax shr al,1 ; prepare upper nibble shr al,1 shr al,1 shr al,1 call prnnib ; print it pop axprnnib: and al,#0x0F ; prepare lower nibble add al,#0x30 cmp al,#0x39 ; convert it into hex jle prnchr add al,#7prnchr: push bx mov ah,#0x0E ; print it mov bl,#0x07 xor bh,bh int 0x10 pop bx ret;----------------------------------------------------------------------------magic: .byte 0xE4,0xE4badmagic:.byte 0xa,0xd .ascii "There does not appear to be a ROM image attached to the" .ascii "flash EPROM utility;" .byte 0xa,0xdresetmsg:.ascii "Reboot to proceed..." .byte 0 welcome:.byte 0xa,0xd .ascii "Flash EPROM programming utility V1.0" .byte 0xa,0xd .ascii "Copyright (c) 1997 by M. Gutschke <gutschk@uni-muenster.de>" .byte 0xa,0xd .ascii "===========================================================" .byte 0xa,0xdprompt: .byte 0xa,0xd .ascii "Enter base address for AMD29F010 flash EPROM on FlashCard or" .byte 0xa,0xd .ascii "press <RETURN> to start autoprobing; the base address has" .byte 0xaclrline1:.byte 0xd .ascii "to be in the range C800..E600: " .ascii " " .byte 0x8,0x8,0x8,0x8 .byte 0delchar:.byte 0x8,0x20,0x8 .byte 0automsg:.ascii "autoprobing... " .byte 0failmsg:.ascii "failed!"basemsg:.byte 0xaclrline2:.byte 0xd .ascii "Enter base address: " .ascii " " .byte 0x8,0x8,0x8,0x8 .byte 0fndmsg: .byte 0xa,0xd .ascii "Found flash EPROM at: " .byte 0alignmsg:.byte 0xa,0xd .ascii "FlashCard requires the hardware address to be aligned to a" .byte 0xa,0xd .ascii "32kB boundary; automatically adjusting..." .byte 0 nofndmsg:.byte 0xa,0xd .ascii "No AMD29F010 flash EPROM found" .byte 0ersmsg: .byte 0xa,0xd .ascii "Erasing old contents... " .byte 0prg1msg:.ascii "done" .byte 0xa,0xd .ascii "Programming from " .byte 0 prg2msg:.ascii ":0000 to " .byte 0donemsg:.ascii "done!" .byte 0xa,0xd .byte 0 failresmsg: .ascii "failed!" .byte 0xa,0xd .byte 0;---------------------------------------------------------------------------- .align 16 .org *-1 .byte 0x00romdata:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -