Hello out there.
Nice to see a undead MASM forum :U
Few words about me:
I´m from Switzerland (sry for my freestyle English), i´m a hobby programmer since years (DOS) and i work at the moment with VIRTUALBOX/DOS 6.22/MASM 6.11. I know a bit of programming ASM (thanks to Peter Norton´s assembling book).
Now i need your help. I try to write a PCX loader for a game i write. Until now, i have all graphics directly integrated into my source. Now i will outsource them into Photoshop compatible files. I think PCX is a good choice. Any objections against PCX?
I have hard-coded the graphics into my ASM sources as variables, cause i don´t know how to access and handle files :red
Now i learned how to handle files, but something is going wrong. Some code first:
;create_file
MOV AH,3Ch
XOR CX,CX
LEA DX,FILENAME
INT 21h
;write_file
MOV BX,AX
MOV AH,40h
MOV CX,40
LEA DX,WRITEBUFFER
INT 21h
;open_file
MOV AH,3Dh
XOR AL,AL
LEA DX,FILENAME
INT 21h
;read_file
MOV BX,AX
MOV AH,3Fh
MOV CX,40
LEA DX,READBUFFER
INT 21h
;write bytes readed from file to videoram
MOV AX,VGASEG
MOV ES,AX
MOV DI,32140
LEA SI,READBUFFER
MOV CX,20
REP MOVSB
############
VGASEG EQU 0A000h
FILENAME DB 'file.nme',0
WRITEBUFFER DB 4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8,4,8
READBUFFER DB ?
Create and write to file works. Open and read out may work, i´m not sure, i think no. Write to videoram works. But i become just random color values, not red/gray (4,8,...). If i change LEA SI,READBUFFER to LEA SI,WRITEBUFFER, i become the right color values. So i think, the failure is between opening/reading file and writing the bytes to WRITEBUFFER.
Can anyone help me? I Just try to open a file, read out the color values into ram (to WRITEBUFFER) and copy them from ram to videoram. Nothing very special i know :lol
Kindly regards,
keinplan
welcome to the forum
when you create the file using 3Ch, it is opened in write mode
after you write to the file, you should close it before trying to open it for reading
that should force the file to actually be written and close
function AH=3Eh is close file, handle in BX
also, when you open the file, you must specify a mode in AL
0 read only
1 write only
2 read/write
in this case, you could use MOV AX,3D00h, open file for read
once you are done reading the file, close it again using AH=3Eh
i figure you have the DS register pointing to the data segment
all of those functions set the carry flag if there is a file error - you have no error handling
i highly recommend Ralf Brown's Interrupt List...
http://www.masm32.com/board/index.php?topic=12926.msg100104#msg100104
not sure about the video stuff - i guess you are in mode 13h ?
Thanks for welcome dedndave :U
Quotealso, when you open the file, you must specify a mode in AL - MOV AX,3D00h
I specify a mode (00h - read only):
MOV AH,3Dh
XOR AL,AL
I think that´s the same then MOV AX 3D00h.
Quotei figure you have the DS register pointing to the data segment
DS must be right (DATASEG), cause write from WRITEBUFFER to File works.
Quoteall of those functions set the carry flag if there is a file error - you have no error handling
I know. But it´s a little trouble to handle all errors just writing a first alpha-version of a function :wink
QuoteRalf Brown's Interrupt List
Are there peoples don´t know Ralf Brown? :U
i guess you are in mode 13h
Yes at the moment. To avoid problems while bank switching in vesa modes for a first pcx loader version. But thats next step, to use a 24bit vesa mode. All at it´s time.
I try now to close the file.
ps: i have a little mistake with READBUFFER/WRITEBUFFER in my first post. READBUFFER is where i store the data from file to write it to videoram. WRITEBUFFER is where i get the data to write it to file ::)
Greetz,
keinplan
sorry about that - i did not see the XOR AL,AL :P
i never tried this, but you could possibly read the file directly into the video segment
DS holds the buffer segment, so...
;read file directly to video buffer
MOV BX,AX
PUSH DS
MOV AX,VGASEG
MOV DS,AX
MOV AH,3Fh
MOV CX,20
MOV DX,32140
INT 21h
POP DS
either way, good luck :U
Hi,
Welcome to the forum.
Quote from: keinplan on April 25, 2010, 01:28:02 AM
Now i need your help. I try to write a PCX loader for a game i write. Until now, i have all graphics directly integrated into my source. Now i will outsource them into Photoshop compatible files. I think PCX is a good choice. Any objections against PCX?
PCX is not bad, but as it is a compressed format, I would
think starting out with an uncompressed format would be
easier. TGA is an uncompressed format that is simple to
use. (And it has an RLE variant as well if wanted.) I have
used PCX in one of my programs, but it is generally not
my first choice.
Your sample data should have a run of duplicate data
to test the RLE compression of PCX. Just thinking ahead.
Regards,
Steve N.
BMP is also a very simple uncompressed format
Hello Steve, thanks for welcome.
Okay, i will check the TGA/BMP/PCX which one are easier. RLE compression isn´t the problem i think. PCX file header is very easy, that´s why i think PCX is a good choice. But ... i compare it first with the other two :U
Some hours later ... it was really simply my fault not to close the file before reopening it to read out. Thanks dedndave, it works now.
One problem rest. After creating a new file (and close it), i open it and try to write to it. But there´s always a 'access denied' failure?! My head´s exploding ... do you can help?
Working testcase (faulty function calls are outcommented // sry, code´s little longer):
CGROUP GROUP CODE_SEG, DATA_SEG
ASSUME CS:CGROUP, DS:CGROUP
CODE_SEG SEGMENT
ORG 100h
INIT_PROGRAMM PROC NEAR
MOV DX,MODE13
CALL SCREEN_MODE
XOR CX,CX ;create_file
LEA DX,FILENAME
CALL CREATE_FILE
;MOV BX,AX ;close_file
;CALL CLOSE_FILE
;XOR AL,AL ;open_file
;LEA DX,FILENAME
;CALL OPEN_FILE
MOV BX,AX ;write_file
MOV CX,192
LEA DX,WRITEBUFFER
CALL WRITE_FILE
CALL CLOSE_FILE ;close_file
XOR AL,AL ;open_file
LEA DX,FILENAME
CALL OPEN_FILE
MOV BX,AX ;read_file
MOV CX,192
LEA DX,READBUFFER
CALL READ_FILE
CALL CLOSE_FILE ;close_file
MOV AX,VGASEG ;write stuff to vram
MOV ES,AX
MOV DI,30232
LEA SI,READBUFFER
MOV DX,12
COPY_GRAPHIC:
MOV CX,16
REP MOVSB
ADD DI,304
DEC DX
JNZ COPY_GRAPHIC
CALL END_PROGRAMM
INIT_PROGRAMM ENDP
;****************************************
CREATE_FILE PROC NEAR
PUSHF
MOV AH,3Ch
INT 21h
JNC FILE_CREATED
MOV AH,2h
MOV DL,41h
INT 21h
FILE_CREATED:
POPF
RET
CREATE_FILE ENDP
;****************************************
;****************************************
OPEN_FILE PROC NEAR
PUSHF
MOV AH,3Dh
INT 21h
JNC FILE_OPENED
MOV AH,2h
MOV DL,42h
INT 21h
FILE_OPENED:
POPF
RET
OPEN_FILE ENDP
;****************************************
;****************************************
CLOSE_FILE PROC NEAR
PUSH AX
PUSHF
MOV AH,3Eh
INT 21h
JNC FILE_CLOSED
MOV AH,2h
MOV DL,43h
INT 21h
FILE_CLOSED:
POPF
POP AX
RET
CLOSE_FILE ENDP
;****************************************
;****************************************
WRITE_FILE PROC NEAR
PUSHF
MOV AH,40h
INT 21h
JNC FILE_WRITTEN
MOV AH,2h
MOV DL,44h
INT 21h
MOV AH,59h ;get extended failurecodes
XOR BX,BX
INT 21h
MOV AH,2h ;print it out
MOV DL,BH
INT 21h
FILE_WRITTEN:
POPF
RET
WRITE_FILE ENDP
;****************************************
;****************************************
READ_FILE PROC NEAR
PUSHF
MOV AH,3Fh
INT 21h
JNC FILE_READED
MOV AH,2h
MOV DL,45h
INT 21h
FILE_READED:
POPF
RET
READ_FILE ENDP
;****************************************
;****************************************
SCREEN_MODE PROC NEAR
PUSH AX
MOV AX,DX
INT 10h
POP AX
RET
SCREEN_MODE ENDP
;****************************************
;****************************************
END_PROGRAMM PROC NEAR
;MOV DX,MODE03
;CALL SCREEN_MODE
MOV AX,4C00h
INT 21h
END_PROGRAMM ENDP
;****************************************
CODE_SEG ENDS
DATA_SEG SEGMENT
MODE03 EQU 3h
MODE13 EQU 13h
VGASEG EQU 0A000h
FILENAME DB 'pac.img',0
WRITEBUFFER DB 15,15,15,15,42,42,42,42,42,42,42,42,15,15,15,15
DB 15,15,42,42,42,42,42,42,42,42,42,42,42,42,15,15
DB 42,42,42,42,42,42,42,15,15,42,42,42,42,42,42,15
DB 15,15,42,42,42,42,42,42,42,42,42,42,42,42,42,42
DB 15,15,15,15,15,42,42,42,42,42,42,42,42,42,42,42
DB 15,15,15,15,15,15,15,42,42,42,42,42,42,42,42,42
DB 15,15,15,15,15,15,15,15,15,42,42,42,42,42,42,42
DB 15,15,15,15,15,15,15,15,15,42,42,42,42,42,42,42
DB 15,15,15,15,15,15,42,42,42,42,42,42,42,42,42,42
DB 42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,15
DB 15,15,42,42,42,42,42,42,42,42,42,42,42,42,15,15
DB 15,15,15,15,42,42,42,42,42,42,42,42,15,15,15,15
READBUFFER DB ?
DATA_SEG ENDS
END INIT_PROGRAMM
hi again, keinplan
attached is an edited version
i modified the file routines so that they could be used with more than one open file
i have added "context variable error reporting"
i added "wait for keypress" code after the screen is drawn
i also made a few other little edits
i have not tested it :P
let me know how it works (or doesn't - lol)
What happens with my code? New version looks like after a hurrican attack :toothy :lol
It works :U and there are some good things into your code, thanks, i have to learn to understand them.
What´s better and why?
MOV DX,OFFSET FILENAME
or
LEA DX,FILENAME
MOV DX,OFFSET Label
assembles to
MOV DX,immed
it is probably smaller and a little faster than LEA
you use MOV r16,OFFSET if the assembler can calculate the address at assembly-time
you use LEA if the processor calculates the address at run-time
LEA DX,Label[BX-5]
LEA - the processor will calculate the address of Label[BX-5] and put it in DX