Reputation: 45
I have this program underneath and it counts to 100 using DOSBox. It works perfectly with .286 but I want to know how can I make this work with .386.
.286
.model small
setCurPos macro x,y
pusha
mov ah, 02h
mov bh, 0
mov dl, x
mov dh, y
int 10h
popa
endm
writeChar macro char,color,ctr
pusha
mov ah, 9
mov al, char
mov bh, 0
mov bl, color
mov cx, ctr
int 10h
popa
endm
delay macro
mov cx, 0fh
mov dx,4240h
mov ah,86h
int 15h
endm
.stack 100h
.data
percentage db 0
ones db ?
tens db ?
.code
org 100
main proc far
mov ax, @data
mov ds, ax
mov es, ax
mov ah, 0
mov al, 13h
mov bh, 0
int 10h
jmp count
to_printHundred:
jmp printHundred
count:
delay
cmp percentage, 64h
je to_printHundred
cmp percentage, 0ah
jae printTens
;printOnes
mov al, percentage
add al, 30h
mov ones, al
setCurPos 10, 10
writeChar ones, 0fh, 1
inc percentage
jmp count
printTens:
xor ax, ax
mov bx, 0ah
mov al, percentage
div bl
add al, 30h
add ah, 30h
mov tens, al
mov ones, ah
setCurPos 10,10
writeChar tens,0fh,1
setCurPos 11,10
writeChar ones,0fh,1
inc percentage
jmp count
printHundred:
mov tens, 31h
mov ones, 30h
setCurPos 10,10
writeChar tens,0fh,1
setCurPos 11,10
writeChar ones,0fh,2
mov ah, 4ch
int 21h
endp
end main
It freezes up and outputs Illegal read/write whenever I use the delay.It sucks having to create relays all the time for conditional jumps when the program is really big.
Upvotes: 1
Views: 505
Reputation: 39190
It freezes up and outputs Illegal read/write whenever I use the delay. It sucks having to create relays all the time for conditional jumps when the program is really big.
This is a problem with DOSBox that faults on the int 15h AH=86h
function.
I worked around the issue by programming a delay mechanism based on the BIOS timer tick. You can find all details in a-low-tech-approach-to-measuring-game-speed
My 1st paragraphs there matches your problem description:
Whilst developing a game I needed a delay routine capable of doing delays ranging from 0.5 sec to just a few msec. The obvious choice was to use the BIOS delay function 86h on int 15h. In a true real address mode environment it works correctly but I saw that an emulator like DOSBox messes up things. Tons of illegal reads and writes. So I had to come up with another solution.
If you're concerned about program size, then you might want to change those macros into subroutines. Each time you invoke a macro all of its code gets inserted in the program whereas a subroutine is encoded once and invoked several times by a mere call
instruction.
.code org 100 main proc far mov ax, @data mov ds, ax mov es, ax
Are you sure that your .model small
program needs this org 100
directive?
If, as indicated in a comment, you've changed to .model tiny
, the ORG
would rather have to be org 256
.
Upvotes: 2