;tool_floppy_disk_wr.rar > Wr.asm, change:2006-04-15,size:9641b
;+FHDR------------------------------------------------------------------------
;
;Copyright (c),
;SuZhou Supereal Microelectronics Confidential Proprietary.
;
;$RCSfile: wr_secs.asm,v $
;
;$Author: yangwenbin/zhangyanan $
;E-mail:figureyang@yahoo.com.cn
;Abstract:
; writes data from hex-file into physical sectors of floppy disc.
;
;Reuse attention:
;1.Coding Style.
;
;$Id: OTHERS.INC,v 1.1.1.1 2006/3/6 18:02:20 yangwenbin/zhangyanan Exp $
;
;-FHDR------------------------------------------------------------------------
;=============================================================================
; usage:
; Usage:wr sourcefilename 0x115600 0x3000
;=============================================================================
.386
.MODEL SMALL
SSEG SEGMENT STACK
DB 256 DUP(?)
SSEG ENDS
CSEG SEGMENT USE16
ASSUME CS:CSEG, DS:CSEG, SS:SSEG
START: CALL FAR PTR GET_CMDPARAMS ;读取命令行参数
JC QUIT_TO_DOS ;命令行参数异常,返回DOS
MOV AX, CS
MOV DS, AX
MOV ES, AX
LEA SI,PARA2_BUF ;调用函数将读取的命令行参数2和3转换成十六进制逻辑扇区号和写长度
LEA DI,SEC_START
CALL FAR PTR CONVERTER
JC QUIT_TO_DOS ;转换异常,返回DOS
LEA SI,PARA3_BUF
LEA DI,SEC_NUM
CALL FAR PTR CONVERTER
JC QUIT_TO_DOS ;转换异常,返回DOS
CALL OPEN_SOURCE
JNC OPEN_FILE_OK
LEA DX,PMT_FAIL
MOV AH,9
INT 21H
JMP QUIT_TO_DOS ;打开文件异常,返回DOS
;
OPEN_FILE_OK: MOV BP, SEC_NUM
RE_W: CALL READ_SOURCE ;从文件读512D字节长数据
MOV SI, OFFSET BUF
MOV AX, SEC_START
MOV CX, 0001H
CALL RW_SECTORS ;写一个扇区
;
INC SEC_START
DEC BP
CMP BP, 00H
JNZ RE_W ;重复直至写完
;
QUIT: MOV AH, 3EH
MOV BX, FILE_HANDLE
INT 21H ;关闭文件
QUIT_TO_DOS: MOV AX, 4C00H
INT 21H
POPA
RET
;=============================================================================
;GET_CMDPARAMS
;读取命令行参数
;入口: 命令行参数缓冲区地址
;返回: CY-出错,NC-成功
;=============================================================================
GET_CMDPARAMS PROC NEAR
CLD
MOV AX,CSEG
MOV ES,AX
MOV SI,80H
LODSB
CMP AL,10 ;参数数目判断
JGE PARA_
PARA_UNOK: MOV AX,CSEG
MOV DS,AX
LEA DX,PROMPT
MOV AH,09
INT 21H
STC
RET ;命令参数异常,返回
PARA_: LEA DI,SOURCE_FILENAME
FILTER1: LODSB ;过滤空格
CMP AL,' '
JZ FILTER1
GET_PARA1: CMP AL,' ' ;读取参数1
JZ PARA1_OK
CMP AL,0DH
JZ PARA_UNOK
STOSB
LODSB
JMP GET_PARA1
PARA1_OK: MOV AL,0
STOSB
LEA DI,PARA2_BUF
FILTER2: LODSB ;过滤空格
CMP AL,' '
JZ FILTER2
GET_PARA2: CMP AL,' ' ;读取参数2
JZ PARA2_OK
CMP AL,0DH
JZ PARA_UNOK
STOSB
LODSB
JMP GET_PARA2
PARA2_OK: MOV AL,0
STOSB
LEA DI,PARA3_BUF
FILTER3: LODSB ;过滤空格
CMP AL,' '
JZ FILTER3
GET_PARA3: CMP AL,' ' ;读取参数3
JZ PARA_UNOK
CMP AL,0DH
JZ PARA3_OK
STOSB
LODSB
JMP GET_PARA3
PARA3_OK: MOV AL,0
STOSB
CLC
RET
GET_CMDPARAMS ENDP
;=============================================================================
;CONVERTER
;十六进制字符串转换成十六进制/200H
;入口: 字符串缓冲区首地址寄存器SI
;返回: 结果缓冲区地址寄存器DI,CY-出错,NC-成功
;=============================================================================
CONVERTER PROC FAR
PUSHA
MOV AX,0
MOV DX,0
MOV BL,BYTE PTR [SI] ;检查前缀0x或0X
INC SI
CMP BL,'0'
JNZ HEX_FAIL
MOV BL,BYTE PTR [SI]
INC SI
CMP BL,'X'
JZ PRE_OK
CMP BL,'x'
JNZ HEX_FAIL
PRE_OK: MOV BL,BYTE PTR [SI]
INC SI
CONVTER_LOOP: MOV CX,4 ;前缀OK,执行转换
SHL_4: SAL AX,1 ;DX,AX*16,左移四位
RCL DX,1
LOOP SHL_4
HEX_NUM: CMP BL,'9' ;数字字符,-48
JG HEX_UPPER
CMP BL,'0'
JL HEX_FAIL
SUB BL,48
JMP HEX_OK
HEX_UPPER: CMP BL,'F' ;大写字母,-55
JG HEX_LOWER
CMP BL,'A'
JL HEX_FAIL
SUB BL,55
JMP HEX_OK
HEX_LOWER: CMP BL,'f' ;小写字母,-87
JG HEX_FAIL
CMP BL,'a'
JL HEX_FAIL
SUB BL,87
HEX_OK: ADD AL,BL ;结果累加
ADC AH,0
ADC DX,0
MOV BL,BYTE PTR [SI]
INC SI
CMP BL,0
JNZ CONVTER_LOOP
CNVERT_OK: MOV CX,200H ;返回结果
DIV CX
CMP DX,0
JZ NO_ADD_1:
INC AX
NO_ADD_1: MOV WORD PTR [DI],AX
CLC
POPA
RET
HEX_FAIL: LEA DX,PROMPT_FAIL
MOV AH,9
INT 21H
LEA DX,USAGE
MOV AH,9
INT 21H
STC ;异常返回
POPA
RET
CONVERTER ENDP
;=============================================================================
;RW_SECTORS
;读写指定扇区号,指定数目的连续扇区
;入口: AX为逻辑扇区号,从零开始。CX为读取的扇区数。ES:SI为缓冲区起始地址
;返回: CY-出错,NC-成功
;=============================================================================
RW_SECTORS PROC NEAR
;PUSHA
PUSH CX
XOR CX, CX
MOV BX, 18 ;每磁道的扇区数目, ax % 18 + 1就是物理扇区号,而其商就是含磁头的
; ;磁道号,
; ;因为 扇区号 = 磁道数1*磁头数*扇区数+磁头数1*扇区数+扇区数1-1
; ;那么ax/18的商就是磁道数1*磁头数+磁头数1
; ;其商再除以磁头数商就是磁道数,而余数就是磁头数
; ;逻辑扇区号=(道号i*面数+面号)*每道扇区数+扇区号-1
XOR DX, DX
DIV BX
INC DX ;得到真实的扇区数
MOV CX, DX ;保存到cx
XOR DX, DX ;将得到商,再次除以磁头数目得到
MOV BX, 2 ;HEADCNT
DIV BX
;AX就是磁道数,dx就是磁头数
MOV CH, AL ;磁道的低8位
SHL AH, 6 ;将ah的低二位放到高二位
AND CL, 3FH
AND AH, 0C0H
OR CL, AH ;高二位放到cl的高二位
MOV DH, DL ;将磁头号送入dh
MOV DL, 0 ;驱动器号
POP AX ;获得读取扇区数目
MOV AH, 03h
MOV BX, SI
INT 13H
;POPA
RET
RW_SECTORS ENDP
;=============================================================================
OPEN_SOURCE PROC NEAR
MOV AX, 3D00H
MOV DX, OFFSET SOURCE_FILENAME
INT 21H
;
MOV FILE_HANDLE, AX
CMP AX,2
JNZ OPENED_OK
STC
JMP QUIT_OUT
OPENED_OK: CLC
QUIT_OUT: RET
OPEN_SOURCE ENDP
;=============================================================================
READ_SOURCE PROC NEAR
MOV AX, 3F00H
MOV BX, FILE_HANDLE
MOV CX, 512
MOV DX, OFFSET BUF
INT 21H
;
RET
READ_SOURCE ENDP
;=============================================================================
;-----------------------------------------------------------------------------
SOURCE_FILENAME DB 13 dup (?)
PARA2_BUF DB 13 DUP(?) ;Para buffer
PARA3_BUF DB 13 DUP(?) ;Para buffer
SEC_START DW ? ;= start_address/200H
SEC_NUM DW ? ;= write_len/200H
;
FILE_HANDLE DW 00H
BUF DB 512 DUP (00)
PROMPT DB '3 parameters required',0DH,0AH
USAGE DB 'Usage:wr sourcefilename 0x115600 0x3000',0DH,0AH,'
PROMPT_FAIL DB 'Invalid Hex parameter',0DH,0AH,'
PMT_FAIL DB 'Open file failed!',0DH,0AH,'
; CSEG ENDS END START ;End of File------------------------------------------------------------------ ;+FFTR------------------------------------------------------------------------ ; ;$Log: wr_secs.asm,v $ ; ;-FFTR------------------------------------------------------------------------
使用WR命令在软盘上写入数据
本文介绍了一个名为WR的命令,用于将来自十六进制文件的数据写入软盘的物理扇区。该命令需要三个参数:源文件名、逻辑扇区号和写入长度。操作流程包括读取命令行参数、参数转换、打开文件、读取文件数据并写入扇区,最后关闭文件。注意编码风格和异常处理。
9万+

被折叠的 条评论
为什么被折叠?



