📄 atomtest.asm
字号:
;----------------------------------------------------------------------------;
; ATOMTEST.ASM: A minimal tester for the atoms device driver ;
;----------------------------------------------------------------------------;
; A simple test of ATMS, with minimal error testing. It reads a string from ;
; the keyboard, writes it to the device, and immediately reads from the ;
; device. It also uses itoh to give the length of the result string returned ;
; by the driver. Quit by inputting nothing or by CTRL+C ;
; ;
; To communicate with the ATMS driver, we first open it as if it were ;
; a file, using @Openfile. The system will return a handle, with which, ;
; we can begin communicating to the driver. ;
; ;
; By passing a null terminated string to @Write, you can do the following ;
; if string = '<variable>', search for <variable> ;
; if string = '<variable>=' delete <variable> ;
; if string = '<variable>=value' insert <variable> ;
; This allows us to 'browse' the data stored by ATMS. ;
; ;
; Calling @Read will return the current <variable> text. ;
;----------------------------------------------------------------------------;
include dos.inc ; contains all the @ macros
.model small, c, os_dos
.386
.dosseg
.stack
.data
dname BYTE 'ATMS',0
handle WORD 0
sMenu BYTE cr,lf,' ATMS Sample Device Driver',cr,lf,
cr,lf,' Select Device Function',cr,lf,
cr,lf,' 1. Write to Device Only',
cr,lf,' 2. Read from Device Only',
cr,lf,' 3. Inquire Device Output Status',
cr,lf,' 0. Quit',
cr,lf,' Other Keys: Write & Read',
cr,lf,' Until Return',cr,lf,eom
sPrompt BYTE cr,lf,' Please Press a Key: ',eom
sInput BYTE cr,lf, 'Input? ', eom
sError BYTE cr,lf,lf,'Error: Could not open the driver',cr,lf,eom
sQuit BYTE cr,lf,lf,'Quit',cr,lf,eom
outBuf BYTE 140 dup (?)
output BYTE cr,lf
value BYTE '0000: '
inBuf BYTE 140 dup (?)
inLen WORD SIZEOF inBuf
outLen WORD SIZEOF outBuf
cr EQU 0Dh
lf EQU 0Ah
eom EQU '$'
; Table of hexadecimal digits used for the hex translation
hex BYTE '0123456789ABCDEF'
.code
int2hex PROTO, :WORD, :WORD
.startup
START:
@Openfile dname, 42h ; open the driver named 'ATMS' for
; read/write, no_deny access
jc error ; carry will be set if error
mov handle, ax ; o.w. the handle is in ax
mov ax, 4401h ; function 4401h: set device data
mov bx, handle ; handle of device from Openfile
mov dx, 00a0h ; status: it's a device (bit 7)
int 21h ; and it's in raw/binary mode (bit 5)
; and do the interrupt
Menu_Loop:
@ShowStr sMenu ; show the menu
.WHILE 1
@ShowStr sPrompt ; show the prompt
@GetChar ; get character into ax
push ax ; save ax for later
@ShowChar cr,lf ; for formatting
pop ax ; now is the time
.IF (al == '0') ; if the user wants to quit
jmp quit ; then quit
.ELSEIF (al == '1') ; 1 would be write to device:
; code is somewhat repeated since other
; (in lower loop) is different
@ShowStr sInput ; show a friendly input? message
@Read outBuf, outLen ; read from keyboard (no handle)
.BREAK .IF (ax==2) ; read from keyboard appends a '$'
; after the cr. if we have only cr'$'
; then end the loop
mov bx, ax ; we'll need to use a base pointer
mov outBuf[bx-2],0 ; to set the 'cr' to a 0 (null) so that
; the driver can handle the string
@Write outBuf, outLen, handle ; write the string to the device, the
; actual count is not necessary
.ELSEIF (al == '2') ; 2: read only
call do_read ; do the read
.ELSEIF (al == '3')
mov bx, handle ; get handle into BX
mov ax, 4407h ; function 4407h: Check Dev.Output Stat
int 21h ; do the interrupt
.IF CARRY? ; carry set means error
@ShowStr sQuit ; here you could handle errors
.ENDIF
.ELSE
jmp Input_Loop
.ENDIF ; continue the other loop
.ENDW
;---- loop that reads from keyboard, writes to device, and reads from device
; until nothing inputed
Input_Loop:
.WHILE 1 ; loop for input
@ShowStr sInput ; show a friendly input? message
@Read outBuf, outLen ; read from keyboard (no handle)
.IF (ax==2) ; read from keyboard appends a '$'
jmp Menu_Loop ; after the cr. if we have only cr'$'
.ENDIF ; then end the loop
mov bx, ax ; we'll need to use a base pointer
mov outBuf[bx-2],0 ; to set the 'cr' to a 0 (null) so that
; the driver can handle the string
@Write outBuf, outLen, handle ; write the string to the device, the
; actual count is not necessary
call do_read ; do a read
.ENDW ; cycle the loop
quit: @ShowStr sQuit ; quit: print the quit message
.exit ; and exit
error: @ShowStr sError ; error: print the error message
jmp quit ; and go to quit
;----------------------------------------------------------------------------;
; do_read: reads from device, calls int2hex, prints output. since it's used ;
; in two places, it's a routine ;
;----------------------------------------------------------------------------;
do_read PROC
@Read inBuf, inLen, handle ; read from the device into the inBuf
mov bx,ax ; again need to use a base pointer
mov inBuf[bx-1], cr ; set the '\0' to a cr
mov inBuf[bx],lf ; set a lf after that
mov inBuf[bx+1],eom ; and the end-of-message after that
INVOKE int2hex,ax,ADDR value ; int2hex will write to the '0000'
@ShowStr output ; show the value (followed by inBuf)
ret
do_read ENDP
;----------------------------------------------------------------------------;
; int2hex ;
; Converts a WORD into its hexadecimal representation. ;
; Based on Chapter 4 of the MASM Programmer's guide ;
;----------------------------------------------------------------------------;
int2hex PROC USES ax bx si, number:WORD, string:WORD
mov bx, OFFSET hex ; load table address
mov si, string
mov ax, number ; load value to convert
and ax, 0F000h ; mask out all but the first byte
shr ax, 12 ; shift
xlat ; translate
mov [si], al ; store
mov ax, number ; load value to convert
and ax, 00F00h ; mask out all but the second byte
shr ax, 8 ; shift
xlat ; translate
mov 1[si], al ; store
mov ax, number ; load value to convert
and ax, 000F0h ; mask out all but the third byte
shr ax, 4 ; shift right to get into table index
xlat ; translate
mov 2[si], al ; store as second to last byte
mov ax, number ; load value to convert
and ax, 0000Fh ; mask out all but the last byte
xlat ; translate
mov 3[si], al ; store as last byte in string
ret
int2hex ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -