Opening a file in DOS

Page 2/3
1 | | 3

Par msd

Paragon (1472)

Portrait de msd

03-02-2011, 19:02

now the dos2 version..

ld de,filename
ld a,0
ld c,43H
CALL 5

PUSH BC ; save file handle

LD HL,16384
LD DE,data
LD C,48h
CALL 5

POP BC
LD C,45H
CALL 5
RET

filename: DB "FILENAME.EXT",0
data:

Par Daemos

Paragon (1989)

Portrait de Daemos

03-02-2011, 20:24

Looks alot easier in DOS2 oO It actually is and I fully understand the code.

But hey Smile I have made some progress in DOS1 as well because I think that I have just managed to open the file successfully but still the transfer to RAM doesn't go Crying I now get the FILE not found message in my console if the file isn't there and nothing happens when the file is there. When I read out the RAM adress at which the file should have been transfered to I get nothing.

So I am partially doing it right and partially doing it wrong. MSXDOS hates me. But I will tame the beast. This is the code in short:


;program will read a simple ASCII file and display its character on the screen

org &h0100

calslt: equ &h001c

jp main ;Very nasty and dirty

callsbl:
ld iy,&hfcc0
ld ix,&ha2 ;chput call because I was too lazy to figure the DOS call out ;)
call calslt
ret

main:

ld C,&hf ;open file
ld DE,FCB
call 5
and a
ld hl,err
call NZ, error

;transfer file to RAM
;set blocksize first no clue how big.. 128 bytes I guess

ld hl,FCB
ld de,&he ;set block size adress
add hl,de

ld (hl),128 ;set block size in FCB
 
ld c,27 ;transfer
ld hl,1 ;one block is enough for now
ld de,&h4000 ;somewhere in RAM
call 5

ld c,10
call 5 ;close file

ld hl,&h4000 ;set pointer to this adress
call print

print: ;display whats in the memory with a 0 as the EOF for now

ld a,(hl)
inc hl
call callsbl ;print character
and a
jr  NZ, print
ld c,0
call 5 ;exit


;give error and exit
error:

ld a,(hl)
inc hl
call callsbl ;print character
and a
jr  NZ, error
ld c,0
call 5 ;exit

err: db "FILE NOT FOUND!!!",0

FCB: ;define some kind of FCB
db 0
db "filename"
db "ext"
ds 40

end

Par WORP3

Paladin (861)

Portrait de WORP3

03-02-2011, 22:42

There are multiple faults within your source, you mixed up hex and dec numbers and you are loosing reg DE before closing.
Try reading the example and fix your function call numbers (did send the link before) !:

ORG #100

LD DE,#4000 ;FREE SPACE
LD C,#1A ;SET DATA TRANSFER ADDRESS
CALL 5

LD DE,#5C ;FCB

LD C,#F ;Open
PUSH DE
CALL 5
POP DE

LD HL,1
LD (FCB+#E),HL

LD HL,#4000
LD C,#27 ;Read all (but max 16K)
PUSH DE
CALL 5
POP DE

PUSH HL
LD C,#10 ;Close
CALL 5
POP DE ;DE=Lenght of file = send all of the file

LD HL,#4000
LOOP:
LD A,(HL)
OUT (IOPORT),A ;Send to device
INC HL
DEC DE
LD A,D
OR E
RET Z
JR LOOP

Par Daemos

Paragon (1989)

Portrait de Daemos

03-02-2011, 23:49

Got it to work at last!! LOL! The only wierd thing that remains is that DOS always reads the entire file into RAM no matter what I do. Even if I tell it to transfer 0 blocks I still get the whole file into RAM.

Well at least it works for now. Accept one mystery remains.


ld HL,xxxx ---< no matter what I fill in here I always get the same results. Can somebody please eplain??
ld DE,FCB
ld C,&h27
call 5

Par WORP3

Paladin (861)

Portrait de WORP3

04-02-2011, 13:23

You probably are still not resetting your FCB before using it, probably it's your record size that is way to high ! Don't assume that every value inside your memory is default filled with zero's !

Please take a look at: http://map.grauw.nl/resources/dos2_environment.php#c3_6

Or at least to this one:
21h...24h Random record number, low byte first. This field is optional, it is only required if random or block reads or writes are used. It must be set up before doing these operations and is updated by block read and write but not by random read or write. Also set up by the "set random record" function.

Par Daemos

Paragon (1989)

Portrait de Daemos

04-02-2011, 19:08

thank you for your patience. I will take another look and try tonight/tomorrow lets hope that I get it right this time.

I did clear the FCB before doing the 0x27 call but it gave bad results. I must be doing something wrong there so I will take a good look and see what I can find.

Par Daemos

Paragon (1989)

Portrait de Daemos

05-02-2011, 19:50

Hey it works!! This is how I finally managed to clear the FCB in the correct way. I have no clue why it didn't work at first but it could be deu to some memory writes that completely made my MSX go wild. Now the next day everything boots normal again so I revised the code and gave it another try. This is how I now clear the FCB prior to the RAM transfer:

;Clear the FCB

ld hl,FCB
ld de,&h0e
add hl,de ;set FCB adress to block size
ld (hl),0 ;set the actual block size lower byte
inc hl
ld (hl),4 ;1024 bytes per block

ld hl,FCB
ld de,&h20
add hl,de
xor a
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
;clear FCB adress 20 up to 24

I have also noticed that anything bigger then 16KB is huge trouble. I will soon load a SC5 file into the RAM and see what happens. That file is 25,9 KB and thus I will see what will happen. I have allready loaded another crappy BMP conversion in and I get I nice 128x128 image on screen!! Big smile

Par commodorejohn

Expert (92)

Portrait de commodorejohn

05-02-2011, 20:33

I have also noticed that anything bigger then 16KB is huge trouble. I will soon load a SC5 file into the RAM and see what happens. That file is 25,9 KB and thus I will see what will happen. I have allready loaded another crappy BMP conversion in and I get I nice 128x128 image on screen!! Big smile
Really? The viewer program I posted earlier in the thread loads 48KB in one go, and I've had no trouble with it...

Par WORP3

Paladin (861)

Portrait de WORP3

05-02-2011, 23:10

You also could do something like this somewhere in the beginning, just to clear your fcb !

LD DE,FCB+1 ;DE = File pointer + 1
LD HL,FCB ;HL = File pointer
LD BC,36
SUB A
LD (HL),A
LDIR

To make all kind of settings within your FCB, you could use reg IX very nicely Wink:

LD IX,FCB
LD (IX+14),1 ;Set record size to 1
LD (IX+15),0

Par Daemos

Paragon (1989)

Portrait de Daemos

05-02-2011, 23:11


Really? The viewer program I posted earlier in the thread loads 48KB in one go, and I've had no trouble with it...

I think that you can load as big as you like if you correctly set the blocksizes like in your program. however if you do not set this blocksize, MSXDOS tries to load the file as one chunk. So one block will be bigger then 16KB's. When the blocksize exceeds this value (I know this purely because I did that stupid thing) the system hangs. In the even worser case the entire memory gets overwritten including some parts that propably have a shadow copy of the BIOS+basic. The result: My MSX will no longer boot and the logo is completely FUBAR for about 5 to 10 minutes. I have to switch the machine of and wait for a really really long time until it fixes itself again Wink


You also could do something like this somewhere in the beginning, just to clear your fcb !

LD DE,FCB+1 ;DE = File pointer + 1
LD HL,FCB ;HL = File pointer
LD BC,36
SUB A
LD (HL),A
LDIR

To make all kind of settings within your FCB, you could use reg IX very nicely :

LD IX,FCB
LD (IX+14),1 ;Set record size to 1
LD (IX+15),0

looking interesting. I will try this routine and see how it works. I have not used ldir yet so that will be good practise.

Page 2/3
1 | | 3