I am writing my own interrupt, to transfer 100 bytes from one file to another file. (My interrupt code is 0x88).
What the interrupt does: the interrupt gets two addresses DS:DX - input file; ES:CX - output file, (in .com programs, DS always == to ES, so address will be in DX and CX) with file names in them (ASCIIZ format). The interrupt has to copy the first 100 bytes from the first file to the second file. If there are less than 100 bytes, then fill up the needed amount to be 100 bytes with whitespace (ASCII code 0x20).
Problem: I don't know how to transfer data from the first file to another, because there is no "section .data" (as I know, I might be wrong, but I couldn't find any information on that).
How I am thinking of doing that: I was thinking to read one byte to register and compare that one byte with 0x00 (if it is not the end of the file). And then write one byte to the output file. If the byte is 0x00, that means the end of the file was reached, so I have to fill (100 minus bytes transferred) with whitespace.
Question: How to read one byte in the register (not in the buffer)?
EDIT: I have tried to add section .data into interrupt file. This is what I have got so far. I have a problem adding whitespace (If the input file has less than 100 bytes) in the end.
Input File:
CCCCC
Output file:
CCCCC mov di, .buffer call procFPBCD2ASCIIZ mov dx, di call procPutStr pop dx
Output file has 100 bytes (as needed), but it fills with something else.
%include 'yasmmac.inc'
;------------------------------------------------------------------------
org 100h
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .text ; Code starts here
jmp Settings ;First launch
Old_I88:
dw 0, 0
procWrite:
jmp .next
.next:
mov [writingFile], cx
call procFOpenForReading
jnc .readingFileIsOpened
macPutString 'Error while opening reading file', '$'
exit
.readingFileIsOpened:
mov dx, buffer
mov cx, 100
call procFRead
jc .errorReading
call procFClose
cmp ax, 100
jb .lessThanHundred
jmp .write
.lessThanHundred:
mov dx, [writingFile]
call procFCreateOrTruncate
jc .errorOpenFile
mov dx, buffer
mov cx, ax
call procFWrite
jc .errorWriting
mov cx, 100
sub cx, ax
push cx
xor cx, cx
mov dx, ax
call procFSeekFromBeginning
pop cx
mov dx, whitespace
call procFWrite
jc . errorWriting
call procFClose
jmp .end
.write:
mov dx, [writingFile]
call procFCreateOrTruncate
mov cx, 100
mov dx, buffer
call procFWrite
jc .klaidaRasant
call procFClose
jmp .end
. errorWriting:
macPutString 'Error while writing file', '$'
exit
.errorOpenFile:
macPutString 'Error while opening file', '$'
exit
.errorReading:
macPutString 'Error while reading file.', '$'
exit
.end:
exit
.writingError:
exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
New_I88:
macPushAll ; Saving registers
call procWrite ;
mov ax, 0xb800
mov es, ax
mov ax, 0x6F41
mov di, 0000
mov cx, 0xa0
rep stosw
macPopAll ;
iret ; Return from interrupt
;
;
;
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Settings (after first launch) block. Does not remain in the memory
;
Settings:
; Getting old 88h vector
push cs
pop ds
mov ax, 3588h ; Getting old interrupt vector
int 21h
; Saving old vector
mov [cs:Old_I88], bx
mov [cs:Old_I88 + 2], es
; Setting new 1Ch vector
;lea dx, [New_I88]
mov dx, New_I88
mov ax, 2588h ; Setting interrupt vector
int 21h
macPutString "OK ...", crlf, '$'
;lea dx, [Settings + 1] ; dx - how many bytes
mov dx, Settings + 1
int 27h
%include 'yasmlib.asm'
section .data
buffer:
times 128 db 00
writingFile:
dw 0000
inputFile:
times 128 db 00
outputFile:
times 128 db 00
whitespace:
db ' ', 00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
section .bss
It's because of the error in these 2 lines that your program worked a little bit and not crash right away! The number that you put in DX so that DOS can make your program a (passive) TSR needs to be the number of paragraphs that you want the program to keep for itself. Your instruction loads DX with a number of bytes and in doing so hogs much more memory than is needed. It would seem your 'missing' .data section was present after all. But not in the way it should have been.
This seeking operation prior to writing the padding spaces is totally redundant. The preceding procFWrite will have left the filepointer exactly where you need it.
On entry to your New_I88 interrupt handler, the DS and ES segment registers (whether equal to each other or not) are not pointing to your code. It will be best to open and create the concerned files and then have DS point to your code (Does macPushAll also preserve DS and ES?).
Now you're ready to read from the opened source file 100 or less bytes. If it's less then simply pad the incomplete buffer with the necessary space characters. Don't be tempted to cut corners and preload space characters in the (static) buffer. In practice, this
int 88hservice needs to function correctly time and time again.Once complete, you always write just 100 bytes.
You are writing a .COM program, so don't use sections of any kind.
The 'yasmlib' has the function procFGetChar for this (returning in the CL register).
No, the value from CL doesn't tell you that. When procFGetChar returns with the carry flag clear and AX=0, then the End-Of-File was reached and so nothing valuable is in CL.