Hallo,
ich versuche ein Programm (NASM als Assembler) zu schreiben, welches eigentlich ganz simpel ist:
-> Einen 64 KB-Puffer bereitstellen
-> darin 64 KB einer Datei lesen
-> diese Datei an LPT1 senden (direkt über die Ports).
Hintergrund: An LPT1 (Basisport 0x378) hängt ein DAC, mit dem ich Audiodaten an einen Verstärker senden kann. Timing spielt (noch) keine Rolle, das kann ich mit einer Schleife vorerst verzögern.
Mein Problem: In dem Moment, wo ich den int 21h aufrufe, bricht mein gesamtes Programm zusammen. Den Code zum Berechnen der aktuellen Programmgröße habe ich aus dem Netz.
Vielleicht kann mir jemand helfen; ich poste einfach mal den gesamten Code.
;------------------------------------
;- PLAYER                           -
;- Play RAW audio files on DAC/LPT1 -
;------------------------------------
org 100h
; set program's memory size to 64K (limit of "tiny" COM files) - CS=DS=ES=SS
        mov bx,ss
        mov ax,es
        sub bx,ax
        mov ax,sp
        add ax,14h
        shr ax,4
        add bx,ax
        mov ah,04ah
        int 21h
; get memory (64K)
        mov ah,48h
        mov bx,1000h    ; 4096 * 16 Bytes = 64 KBytes
        int 21h
        push ax
; open the file
        mov ah,3Dh
        mov al,0        ; read only
        mov dx,FILENAME ; ds:dx = ASCIIZ filename
        int 21h
        jc err_fopen
        mov [FILEHANDLE],ax
pop ds                  ; new DS => DS:BX addresses file buffer
; main program loop
;===================
beginmain:
        ; read (next) 64K of file
        mov ah,3Fh
        mov bx,[cs:FILEHANDLE]
        mov cx, 0ffffh
        mov dx,0
        int 21h
        jc err_fread
mov ah,09h
mov dx,msg_debug
int 21h
        mov bx,0                ; begin at address 0 of buffer
        mov dx,[BASE_ADDR]      ; dx = BASE_ADDR
        play:
                mov al,[ds:bx]
                out dx,al
                inc bx
                loop play
endmain:
;===================
; end main loop
; close the file
        mov ah,3Eh
        mov bx,[FILEHANDLE]
        int 21h
        jc err_fclose
; deallocate the memory
        mov ah,49h
        int 21h
        jc err_memclose
jmp end
; write error messages
err_fopen:
        mov ah,09h
        mov dx,msg_err_fopen
        int 21h
        jmp end
        
err_fclose:
        mov ah,09h
        mov dx,msg_err_fclose
        int 21h
        jmp end
err_fread:
        push cs
        pop ds
        mov ah,09h
        mov dx,msg_err_fread
        int 21h
        jmp endmain     ; end the program
err_memresize:
        mov ah,09h
        mov dx,msg_err_memresize
        int 21h
        jmp end
err_memclose:
        mov ah,09h
        mov dx,msg_err_memclose
        int 21h
        jmp end
err_memget:
        mov ah,09h
        mov dx,msg_err_memget
        int 21h
        jmp end
; exit program
end:
        mov ah,4Ch
        mov al,00h
        int 21h
msg_debug db "DEBUG",13,10,36
msg_err_fopen db "Could not open the file!",13,10,36
msg_err_fclose db "Could not close the file!",13,10,36
msg_err_fread db "Could not read the file!",13,10,36
msg_err_memresize db "Could not resize program's memory!",13,10,36
msg_err_memget db "Could not allocate enough memory (64K)!",13,10,36
msg_err_memclose db "Could not deallocate the memory!",13,10,36
FILENAME db "QUAAK.AU",0
FILEHANDLE dw 0
BASE_ADDR dw 0378h
HAVE_NEXTBLOCK db 0
Warum ich nicht in einem Segment bleiben möchte? Wenn ich mit 48h Speicher beschaffe, ist der unabhängig vom Programm und ich kann darauf dann eine Interrupt-Routine draufschmeißen. Außerdem kann ich so den Puffer maximieren.
Achja: Bitte keine 32-Bit-Addressierungen verwenden, das Gerät ist ein 286er.
Gruß,
ein völlig korrupter
Sebastian