shortening loading time for call absolute

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

Post Reply
mikefromca
Coder
Posts: 39
Joined: Wed Oct 16, 2019 11:28 am

shortening loading time for call absolute

Post by mikefromca » Fri Jan 15, 2021 3:55 pm

I made a program in Qbasic that uses assembly code with call absolute. The crazy thing is loading the data into a variable takes a long time in itself. I guess that's the price I pay for convenience.

But this is how I do it. I make my assembly code in linux with nasm then I use xxd utility to extract the hex code I need in the right format, then I paste it into my program. the xxyyxxyy you see in my Qbasic code represents that assembly code in hexadecimal, but since my assembly code is over 1600 bytes long, I needed to put my code across a few lines and concatenate it together so the QuickBasic EXE compiler doesn't break when I make an EXE.

Anyways, here's my code so far:

Code: Select all

asmcode$ = "xxyyxxyyxxyy"......
asmcode$ = asmcode$+ "xxyyxxyyxxyy"......
asmcode$ = asmcode$+ "xxyyxxyyxxyy"......

d$=""
for c% = 1 to len(asmcode$) step 2
d$=d$+chr$(val("&H"+mid$(asmcode$,c%,1)))
next c%
I know the slowness lies within the for-next loop because I'm dealing with converting each individual byte to an actual machine character and then d$ equals all of the bytes as machine language.

I want to avoid loading the machine code as a file because I want it internal to my program.

I thought of using MKL$ but for that don't the hex codes have to be reversed for that to work?

Is there another way I can make that for-next loop execute faster?

MikeHawk
Coder
Posts: 38
Joined: Sun Jul 08, 2018 11:23 am

Re: shortening loading time for call absolute

Post by MikeHawk » Sat Jan 16, 2021 9:22 am

Way back when, we used to simply store assembly code in hexadecimal text-form in DATA statements... I'd replace the target string with an INTEGER array and use POKE to fill it faster. This would remove the need for the CHR$() and would also avoid resizing strings on-the-fly, which is much slower than modifying the content of an already sized buffer: when you do d$ = d$ + "x", QuickBASIC creates a temporary string for d$ + "x" (which gets bigger with every step of the loop), then it copies that many bytes into the newly created d$ target - fairly certain this is where most of the time is wasted; if you want to stick to the string for your buffer, you could try:

Code: Select all

' Interrupt 33 (mouse)
DATA 58
DATA 5589E58B5E0C8B07508B5E0A8B07508B
DATA 5E088B0F8B5E068B175B581E07CD3353
DATA 8B5E0C8907588B5E0A89078B5E08890F
DATA 8B5E0689175DCA080000

READ numBytes%
Target$ = STRING$(numBytes%, 0)
Offset% = 1
DO
	READ Source$
	Half% = LEN(Source$) \ 2
	' convert hexadecimal (text-form) to binary
	FOR i% = 0 TO Half% - 1
		MID$(Source$, 1 + i%, 1) = CHR$(VAL("&h" + MID$(Source$, 1 + i% * 2, 2)))
	NEXT i%
	' shove into target buffer
	MID$(Target$, Offset%, Half%) = MID$(Source$, 1, Half%)
	Offset% = Offset% + Half%
LOOP WHILE (Offset% < numBytes%)
That being said, a code that takes 1600 bytes in binary will take 3 times that space in QuickBASIC (3200 bytes for the text-form plus 1600 bytes for the binary form created by the loop) and it will load much slower than just reading from a binary file right away. But you do you.

mikefromca
Coder
Posts: 39
Joined: Wed Oct 16, 2019 11:28 am

Re: shortening loading time for call absolute

Post by mikefromca » Tue Jan 19, 2021 8:23 pm

I decided now that I'm taking a more elegant approach.

My long code now is now part of my own DOS TSR that is loaded first before QB is started, then I made a mini stub assembly routine that can check to see if the TSR is installed and that runs the interrupt. That stub routine takes about 105 bytes, so my load speed is significantly faster.
Another nice thing about the TSR is that I have managed to reserve 57KB of conventional memory that I can directly access with QB. Without this, I think the most I could do with QB alone with all variables is about 32KB or 48KB I can't remember. because back in the day when I was more heavy on the QB side of programming I did get out of string space errors and such for declaring large variable space.

angros47
Veteran
Posts: 78
Joined: Mon Sep 08, 2008 12:52 pm
Contact:

Re: shortening loading time for call absolute

Post by angros47 » Sun Feb 07, 2021 5:50 pm

Can't you compile it to a .OBJ file, then make a QLB and a .LIB file? Or link it directly?

mikefromca
Coder
Posts: 39
Joined: Wed Oct 16, 2019 11:28 am

Re: shortening loading time for call absolute

Post by mikefromca » Fri Feb 26, 2021 2:08 pm

I ended up making my own C program that converts any binary file into a series of MKL$ statements then instead of me running a for-next loop to go through pairs of hex digits, I just did concatenation of mkl$ statements. More like:

Code: Select all

asm$=mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)....
asm$=asm$+mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)....
asm$=asm$+mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)+mkl$(&Hnnn)....
....
The loading time is significantly reduced but I have to use concatenation for large code because QB doesn't like lines that are too long when compiling.

Post Reply