I was trying to run some simple machine code programs in QuickBasic (4.5 and QBX 7.1) and QBasic from DosBox-X. The program should output a character "A" (code 65) to the screen using int 21h and AH=2 subroutine.
(A more ambitious goal is to print a whole string with int21h/ah=9, but right now I am stuck here.)
This is an example from qbasic.com:
'Create a machine-language procedure and
'call it using CALL ABSOLUTE
'Array to store machine code
DIM asmroutine(1 TO 6) AS INTEGER
'Data that makes up machine-code routine
DATA &H55 : ' PUSH BP
DATA &H8B, &HEC : ' MOV BP, SP
DATA &HB4, 2 : ' MOV AH, 2
DATA &H2, 65 : ' MOV DL, 65
DATA &HCD, &H21 : ' INT 21H
DATA &H5D : ' POP BP
DATA &HCB, 0 : ' RET
'Get array offset
offset = VARPTR(asmroutine(1))
'Change the segment to the start of the array
DEF SEG = VARSEG(asmroutine(1))
'Fill the array with machine code
FOR i = 0 TO 11
READ asmcode
POKE (offset + i), asmcode
NEXT i
'Call the routine and restore the segment
CALL ABSOLUTE(VARPTR(asmroutine(1)))
DEF SEG
Running this program either gives an error "Division by zero" on Windows PC (QBX) or crashes DosBox on Android, as well as in the web-based versions like https://dos.zone/qbasic-1991/
There is no problem executing it in assembly.
I was able however to run the following program using int 10h to print characters on Android-based DosBox, but on my PC it still gives "Division by zero":
CLS
DIM PM%(5)
SegPM% = VARSEG(PM%(0))
OffPM% = VARPTR(PM%(0))
DEF SEG = SegPM%
FOR I% = 0 TO 11
READ Octet$
POKE OffPM% + I%, VAL("&H" + Octet$)
NEXT I%
CALL ABSOLUTE(OffPM%)
DEF SEG
END
'machine code
DATA B4,0A 'MOV AH,0A
DATA B0,61 'MOV AL,61
DATA B7,00 'MOV BH,0
DATA B9,78,00 'MOV CX,78
DATA CD,10 'INT 10
DATA CB 'RETF
How to execute the program above in QB?