Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

4 Gigabyte mit Quickbasic nutzen - Anwendung des Unreal Mode
Gehe zu Seite 1, 2, 3  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 10.09.2007, 21:33    Titel: 4 Gigabyte mit Quickbasic nutzen - Anwendung des Unreal Mode Antworten mit Zitat

Nachdem ich mich mit dem Unreal Mode beschäftigt hatte dachte ich es wäre wohl relativ leicht dies auch mit Quickbasic zu machen. Nun es hat doch etwas länger gedauert. zwinkern

Es ist schon interessant, in dieser Weise den ganzen eingebauten Speicher erreichen zu können. Leider geht es nicht in der DOS-Box sondern nur mit reinem DOS.

Die Kommentare sind in englisch da ich hoffe, daß sich auch englisch sprechende Programmierer für dieses Beispiel interessieren.

Georg

Code:

'
'This sample shows how to enable Unreal mode (Big real mode, flat mode etc.)
'from Quickbasic. In Unreal mode Quickbasic programs can address all memory
'above one Megabyte up to 4 Gigabytes using a 32bit offset
'                                                     
'Will not run with EMM386, a DOS Box in Windows or otherwise in
'protected mode - which is how most DOS programs are used today.
'On the other hand, it will run in Bochs or VMWare.
'
'features which could be added: copy routines from below 1 MB to above,

'enable A20 line, determine available and unused memory above 1 MB etc.
'
'2007 Georg Potthast
'
'References: Alexei Frounze, Rick Elbers, Gunter Ilzig, Erika Schulze,
'Petter Holmberg, Jens Hohmuth
'
DECLARE SUB PMODE.DETECT (PM%)            'are we in pmode ?
DECLARE SUB START.UNREAL ()               'start unreal mode
DECLARE FUNCTION A20OFF% ()               'HIMEM.SYS will enable A20 line

CLS
PRINT "Welcome to the Unreal Mode sample!"

'check if A20 line is enabled
IF A20OFF% = 1 THEN PRINT "A20 not enabled - Unreal mode cannot be used": END

'check if PC is already in PMode due to Windows or EMM386
CALL PMODE.DETECT(PM%)
IF PM% THEN PRINT "We are in PMODE or V86 mode..": END

PRINT "Entering Unreal Mode using CR0";
CALL START.UNREAL

'write to video memory using a zero segment in ES and a 32bit offset in EAX
'so we are not using &HB800:0000 but &H0000:000B8000
'putting a higher value in EAX we can address up to 4 Gigabyte

FOR i% = &H1E0 TO &H1000 STEP &H10

asm$ = ""
asm$ = asm$ + CHR$(&H33) + CHR$(&HDB)              'XOR BX,BX -> BX=0
asm$ = asm$ + CHR$(&H8E) + CHR$(&HC3)              'MOV ES,BX -> ES=0
asm$ = asm$ + CHR$(&H66) + CHR$(&HB8) + CHR$(&H0)  'MOV EAX,&HB8000 - 32 Bit!
asm$ = asm$ + CHR$(&H80) + CHR$(&HB) + CHR$(&H0)   'continue line above
asm$ = asm$ + CHR$(&H5) + MKI$(i%)                 'ADD AX,i% - increment here
asm$ = asm$ + CHR$(&HBB) + CHR$(&H1) + CHR$(&HF)   'MOV BX,&H0F01 - Smiley
asm$ = asm$ + CHR$(&H26) + CHR$(&H67) + CHR$(&H89) 'MOV ES:[EAX],BX - write it
asm$ = asm$ + CHR$(&H18)                           'continue line above
asm$ = asm$ + CHR$(&HCB)                           'retf

DEF SEG = VARSEG(asm$): CALL ABSOLUTE(SADD(asm$)): DEF SEG

NEXT i%

END

FUNCTION A20OFF%

'check whether A20 line is enabled

'save byte at 0:4F0
        DEF SEG = 0
        a% = PEEK(&H4F0)
'write &HE7 at location 0:4F0h
        POKE &H4F0, &HE7
'now try to read this byte with wraparound
        DEF SEG = &HFFFF
        b% = PEEK(&H500) '&H4F0+&H10
'write back saved byte to 0:4F0h
        DEF SEG = 0
        POKE &H4F0, a%
'if equal, wraparound is possible, A20 is not enabled
        IF b% = &HE7 THEN A20OFF% = 1

END FUNCTION

SUB PMODE.DETECT (PM%)
'determine if we are in REAL mode

asm$ = ""
asm$ = asm$ + CHR$(&H55)                           'PUSH BP
asm$ = asm$ + CHR$(&H89) + CHR$(&HE5)              'MOV BP,SP
asm$ = asm$ + CHR$(&HF) + CHR$(&H1) + CHR$(&HE0)   'MOV EAX,CR0
asm$ = asm$ + CHR$(&H24) + CHR$(&H1)               'AND AL,1 MASK BIT 1(PE FLAG)
asm$ = asm$ + CHR$(&H8B) + CHR$(&H5E) + CHR$(&H6)  'MOV BX,[BP+06]
asm$ = asm$ + CHR$(&H88) + CHR$(&H7)               'MOV [BX],AL
asm$ = asm$ + CHR$(&H5D)                           'POP BP
asm$ = asm$ + CHR$(&HCA) + CHR$(&H2) + CHR$(&H0)   'RETF 2

DEF SEG = VARSEG(asm$): CALL ABSOLUTE(PM%, SADD(asm$)): DEF SEG

END SUB

SUB START.UNREAL

'setup Global Descriptor Table for 4 Gigabyte
DIM gdt%(7)
gdt%(0) = 0: gdt%(1) = 0: gdt%(2) = 0: gdt%(3) = 0
gdt%(4) = &HFFFF: gdt%(5) = 0: gdt%(6) = &H9200: gdt%(7) = &HCFFF
'calculate physical address of gdt%()
temp& = VARSEG(gdt%(0))
temp& = temp& * 16
temp& = temp& + VARPTR(gdt%(0)) 'now 20bit address in temp&
temp& = temp& AND &HFFFFF
'setup GDTR value
gdtptr$ = MKI$(16) + MKL$(temp&)

asm$ = ""

'load gdt
asm$ = asm$ + CHR$(&HBB) + MKI$(VARSEG(gdtptr$)) 'mov bx,seg gdtptr$
asm$ = asm$ + CHR$(&H8E) + CHR$(&HC3)            'mov es,bx
asm$ = asm$ + CHR$(&HBB) + MKI$(SADD(gdtptr$))   'mov bx,offset gdtptr$
asm$ = asm$ + CHR$(&H26) + CHR$(&HF) + CHR$(&H1) + CHR$(&H17) 'lgdt es:[bx]

asm$ = asm$ + CHR$(&HFA) 'cli ;disable interrupts
asm$ = asm$ + CHR$(&H1E) 'push DS
asm$ = asm$ + CHR$(&H6)  'push ES

'enter PMode
asm$ = asm$ + CHR$(&HF) + CHR$(&H1) + CHR$(&HE0)   'MOV EAX,CR0
asm$ = asm$ + CHR$(&HC) + CHR$(&H1)                'OR AL,1 SET BIT 1(PE FLAG)
asm$ = asm$ + CHR$(&HF) + CHR$(&H22) + CHR$(&HC0)  'MOV CR0,EAX ;set PMode flag in CR0 now

asm$ = asm$ + CHR$(&HEB) + CHR$(&H0) 'jmp short

asm$ = asm$ + CHR$(&HBB) + CHR$(&H8) + CHR$(&H0)    'MOV BX, &H08
asm$ = asm$ + CHR$(&H8E) + CHR$(&HDB)               'MOV DS, BX
asm$ = asm$ + CHR$(&H8E) + CHR$(&HC3)               'MOV ES, BX

'leave PMode now
asm$ = asm$ + CHR$(&HF) + CHR$(&H1) + CHR$(&HE0)   'MOV EAX,CR0
asm$ = asm$ + CHR$(&H24) + CHR$(&HFE)              'AND AL,0 CLEAR BIT 1(PE FLAG)
asm$ = asm$ + CHR$(&HF) + CHR$(&H22) + CHR$(&HC0)  'MOV CR0,EAX ;clear PMode flag in CR0 now

asm$ = asm$ + CHR$(&HEB) + CHR$(&H0) 'jmp short

asm$ = asm$ + CHR$(&H7)  'pop ES
asm$ = asm$ + CHR$(&H1F) 'pop DS
asm$ = asm$ + CHR$(&HFB) 'sti ;start interrupts again

asm$ = asm$ + CHR$(&HCB) 'retf

DEF SEG = VARSEG(asm$): CALL ABSOLUTE(SADD(asm$)): DEF SEG

END SUB


Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 10.09.2007, 21:49    Titel: Antworten mit Zitat

Also, DAS da kenn ich als Protected Mode, aber Unreal Mode is ja auch mal ne nette Umschreibung happy

Jetz musst nur noch fbgfx2 portiern und schon hast fast FreeBASIC grinsen grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 11.09.2007, 07:13    Titel: Antworten mit Zitat

Man schaltet nur kurz in den protected mode und wieder zurück. Dann bleibt man im real mode und adressiert mit einem 32bit offset.

Näheres zum Thema gibt es hier:

http://de.wikipedia.org/wiki/Real_Mode

http://en.wikipedia.org/wiki/Unreal_mode
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 16.09.2007, 14:23    Titel: Antworten mit Zitat

Soweit ich das verstanden habe, ist diese weise eine Art von "DOS Protected Mode Interface", welcher in QB geschrieben ist, nur eben mit 4GB Support zwinkern
Siehe dazu auch
http://de.wikipedia.org/wiki/DPMI

Du kannst das QB Programm als loader benutzen um so zb einen virtuellen Speicherbreich zu erstellen..
So in der hat hat es ja schon WIN95,98 gemacht, immerhin..
Dennoch kommt man damit nicht um highmem und EMM386 herum, welche die eigendliche Arbeit abnehmen..
_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 16.09.2007, 15:00    Titel: Antworten mit Zitat

DPMI ist viel umfangreicher als der Unreal Mode. Der DPMI Standard erwartet, daß die DOS-Programme in einer virtuellen Machine laufen, z.B. eine Windows-Dos-Box. Siehe dazu auch:

http://www.fh-zwickau.de/doc/prmo/pmtutor/text/p_dos3.htm

Der Unreal Mode funktioniert nur, wenn kein emm386 Treiber läuft!

Vielleicht kann man es so erklären:

Im Real Mode addressiert man 16Bit-Segment : 16Bit-Offset.

Nach Einschalten des Unreal Mode kann man adressieren:
16 Bit-Segment : 32Bit-Offset. Da mit einem 32Bit-Offset 4 Gigabyte adressiert werden können, setzt man das Segment auf Null und verwendet einfach 0:32Bit Offset.

Um das Beispiel praktisch einsetzbar zu machen, muß man noch eine Kopier-Routine schreiben um Daten über 1 MB zu kopieren und wieder zurück. Diese Routine ist dann vergleichbar mit XMS, es geht wohl nur einfacher und schneller.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 16.09.2007, 15:47    Titel: Antworten mit Zitat

Georgp24 hat Folgendes geschrieben:
Der Unreal Mode funktioniert nur, wenn kein emm386 Treiber läuft!

Das hab ich immer so an den Demos und Spielen der Gruppe Rennaisance gehasst... Haben erweiterten Speicher gebraucht, aber EMM386 und HIMEM musste deaktiviert werden (und ist bei mir auch standardmäßig aktiviert)...
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 16.09.2007, 16:43    Titel: Antworten mit Zitat

Wie ich im Kommentar zum Beispiel geschrieben habe ist es der Nachteil des Unreal Mode, dass emm386 deaktiviert sein muß und das Programm nicht in einer DOS-Box läuft.

Himem kann allerdings laufen.

Es kann auch mit Bochs oder VMWare verwendet werden.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 21.09.2007, 21:20    Titel: Antworten mit Zitat

Ich seh darin dennoch keinen Sinn...

Man ist also noch im Realmode, kann aber auf 4 GB RAM VOLL zugreifen?
D.h. auch Programmcode an &h00039913 schreiben, und diesen per ASM-CALL ausführen?
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 21.09.2007, 22:45    Titel: Antworten mit Zitat

Zuerst zur Sinnfrage. zwinkern Ich denke es ist schon interessant aus Quickbasic heraus über 1 MB zu lesen und zu schreiben. Allerdings weist Jojo zurecht darauf hin, daß man dies kommerziell wohl nicht einsetzen sollte, da der "User" erstmal seinen emm386 Treiber rausschmeißen muß, um das Programm einsetzen zu können.

Ich denke man sollte den Speicher über 1 MB verwenden, um Daten dort zwischenzuspeichern. Man kann sicher Programmcode in diesen Speicherbereich schreiben. Ob dieser dann z.B. mit "call dword ptr" aufgerufen werden kann, habe ich noch nicht probiert.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Wolfi30



Anmeldungsdatum: 17.08.2007
Beiträge: 38

BeitragVerfasst am: 22.09.2007, 12:37    Titel: Antworten mit Zitat

Hi!

Ist doch ein alter Hut, hat doch schon der Bill bei seinen Speichermanagern benutzt teilweise.
Naja, viele denken erst seit Windows95 kann man auf den vollen Speicher zugreifen....Weiss man doch schon seit den 286-386 Prozessoren das dies möglich ist. Leider war zu der Zeit Speicher halt noch teuer

http://en.wikipedia.org/wiki/Unreal_mode
http://www.osdev.org/wiki/Unreal_Mode

Gruß Wolfi
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 22.09.2007, 16:58    Titel: Antworten mit Zitat

Das der Unreal Mode eine neue Erkenntnis ist, habe ich nie behauptet.

Neu ist diesen Mode mit einem Quickbasic Programm zu aktivieren und zu nutzen. (Es sei denn jemand findet ein ähnliches Beispiel.) lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Wolfi30



Anmeldungsdatum: 17.08.2007
Beiträge: 38

BeitragVerfasst am: 23.09.2007, 01:37    Titel: Antworten mit Zitat

Hi!

Mit Quickbasic nicht, aber mit Turbo Pascal hab ich Beispiele gesehen! Schade nur wegen dem Ruf eines nur Hobby-Compilers.
Da ist wenigstens ein Inline-Assembler dabei gewesen seit der Version 6, Quickbasic wäre mir zu umständlich für sowas, bei aller Liebe!

Gruß Wolfi
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 23.09.2007, 09:58    Titel: Antworten mit Zitat

Es ist schon umständlich, die Maschinensprache/Opcodes einzutragen und dann das ganze mit call absolute aufzurufen.

Etwas einfacher geht es mit dem ABSASM21 Programm von Petter Holmberg. Dieses liest einen Assembler-File, läßt diesen von DEBUG compilieren und trägt dann das Ergebnis in einen Quickbasic-File zum Aufruf mit call absolute. Die Assembler Befehle stehen dann als Kommentar hinter den Opcodes. Debug macht aber nur 8086 Assembler.

Das Programm findet sich auf petesqbsite. http://www.petesqbsite.com/sections/tutorials/tutorials/absasm21.zip

Petter Holmberg hat Tutorials dazu geschrieben, die sich auch auf petesqbsite finden.

Da das Programm schon recht alt ist, bedarf es noch einiger Änderungen, damit es wieder läuft.

Georg


Zuletzt bearbeitet von Georgp24 am 23.09.2007, 10:12, insgesamt 2-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Georgp24



Anmeldungsdatum: 30.06.2006
Beiträge: 81
Wohnort: Ahlen

BeitragVerfasst am: 23.09.2007, 10:10    Titel: Antworten mit Zitat

Also hier ist mein gepatchtes Programm:

Code:
' -------------------------------------------------------------------------- '
' Absolute Assembly 2.1 by Petter Holmberg, -97.                             '
'
' including patches by Georg Potthast regarding calls of DEBUG -2007
'                                                                            '
' I've found some bugs in Absolute Assembly 2.0, so here's a new version.    '
' For those of you who haven't used AbsAsm before, here's what it does:      '
'                                                                            '
' The program will let you choose a text file with Assembly source code,     '
' a destination file name and a string variable name. The result will be a   '
' set of commented BASIC string declaration lines in the destination file,   '
' ready to be executed with CALL ABSOLUTE.                                   '
' For example, you may have a text file looking like this:                   '
'                                                                            '
' ; A Useless Program example                                                '
'                                                                            '
'           XOR AX, AX    ; Set AX to 0                                      '
' Loopinit:                                                                  '
'           MOV CX, 4     ; Prepare for a loop                               '
' Increase: INC AX        ; Incease AX by 1                                  '
'           LOOP Increase ; Loop 8 times                                     '
'           CMP AX, 8     ; Is AX 8?                                         '
'           JNZ Loopinit  ; No. Go back to Loopinit                          '
'           RETF          ; Back to BASIC                                    '
'                                                                            '
' Run it through this program and you will get these lines moved into a      '
' selected BASIC program:                                                    '
'                                                                            '
' asm$ = ""                                                                  '
' asm$ = asm$ + CHR$(&H31) + CHR$(&HC0)            ' XOR AX,AX               '
' asm$ = asm$ + CHR$(&HB9) + CHR$(&H4) + CHR$(&H0) ' Loopinit: MOV CX,0004   '
' asm$ = asm$ + CHR$(&H40)                         ' Increase: INC AX        '
' asm$ = asm$ + CHR$(&HE2) + CHR$(&HFD)            ' LOOP Increase           '
' asm$ = asm$ + CHR$(&H3D) + CHR$(&H8) + CHR$(&H0) ' CMP AX,0008             '
' asm$ = asm$ + CHR$(&H75) + CHR$(&HF5)            ' JNZ Loopinit            '
' asm$ = asm$ + CHR$(&HCB)                         ' RETF                    '
'                                                                            '
' Absolute Assembly takes use of DEBUG, the program shipped with MS-DOS.     '
' DEBUG only supports 8088/8086 instructions, but it's still a good tool for '
' getting machine language out of Assembly instructions. And since QBASIC    '
'                                                                            '
' Absolute Assembly 2.1 features:                                            '
' * Support for blank lines and lines with just comments or lables.          '
' * Support for double Assembly commands, like REP STOSB.                    '
' * Option to automatically add CALL ABSOLUTE lines to output file.          '
' * All Assembly source lines printed to BASIC file in the same column.      '
' * Option to merge lines directly into a BASIC file.                        '
' * Auto-detection of QuickBASIC binary files to ensure safe merging.        '
' * Handling of errors and bugs in the sourcefile.                           '
'                                                                            '
' Notes:                                                                     '
' * Comments must start with a semicolon, (;).                               '
' * The maximum number of labels are 256. You shouldn't need half as much.   '
' * The maximum number of letters for a label are 16. It's easy to change    '
' * the program to accept a larger number, but it's probably not necessary.  '
' * A line label must be immediately followed by a colon, (:). Do NOT use a  '
'   colon after the label name in jump-instructions.                         '
' * Never use Assembly opcodes, numbers or single letters as labels.         '
' * Do not name labels so that the name includes the letters REP, REPE or    '
' * REPZ after each other, for example RepeatLoop:                           '
'   "Label:" and "label:" are processed as the same label.                   '
' * If no code string name is specified, it will be asm$ as default.         '
' * This program was made in QB45, but you should be able to run it in       '
'   QBASIC, PDS, VBDOS and PB as well.                                       '
' * If the program locks up, it's probably while running DEBUG. If this      '
'   happens, reboot your computer and check your source code for lines with  '
'   other things than Assembly instrucions, comments, labels or spaces.      '
' * You may use this program freely; distribute it, modify it, learn from it '
'   or erase it from your hard drive. ;) Just be sure to credit me in the    '
'   programs where you have used Absolute Assembly for some of the code.     '
' * If your computer gets damaged while using this program, don't blame me.  '
' * If you use Absolute Assembly in a program, please mail me and tell me    '
'   about it!                                                                '
' * Any comments/suggestions/bug reports etc. can be sent to:                '
'   petter.holmberg@usa.net                                                  '
' * Enjoy the program and have fun! Petter Holmberg, Sweden.                 '
' -------------------------------------------------------------------------- '

'ON ERROR GOTO ErrorHandler

' -------------------------------------------------------------------------- '
' Declaration of constants and arrays:                                       '
' -------------------------------------------------------------------------- '

CONST rundebug$ = "DEBUG.EXE" ' Change this if you have DEBUG on
                 ' another location.
CONST tempfile1$ = "TEMPFIL1.TXT"    ' Change this if the filename already
                 ' is in use.
CONST tempfile2$ = "TEMPFIL2.TXT"    ' Change this if the filename already
                 ' is in use.
CONST tempfile3$ = "TEMPFIL3.TXT"    ' Change this if the filename already
                 ' is in use.
CONST tempfile4$ = "TEMPFIL4.TXT"    ' Change this if the filename already
                 ' is in use.
CONST tempfile5$ = "TEMPFIL5.TXT"    ' Change this if the filename already
                 ' is in use.
CONST errorfile$ = "ERRORS.TXT"      ' Change this if the filename already
                 ' is in use.

TYPE labeltype                       ' Usertype for storing of labels.
  labelname AS STRING * 16           ' Change this if you want longer labels.
  labelpos AS STRING * 4
  labelnum AS INTEGER
END TYPE

DIM label(1 TO 256) AS labeltype     ' Array for storing of labels.

Start:

numlabels% = 0                       ' Label counter.
linecounter% = 1                     ' Line counter.
errorcounter% = 0                    ' Error counter.

' -------------------------------------------------------------------------- '
' Ask for settings:                                                          '
' -------------------------------------------------------------------------- '

CLS

PRINT "Absolute Assembly 2.1 by Petter Holmberg, -97."
PRINT

INPUT "Assembly source text file      : ", sourcefilename$
INPUT "BASIC destination file         : ", destfilename$
INPUT "Name of code string            : ", codestring$

codestring$ = LTRIM$(RTRIM$(codestring$))
IF codestring$ = "" THEN codestring$ = "asm$"
IF RIGHT$(codestring$, 1) <> "$" THEN codestring$ = codestring$ + "$"

PRINT "Append to destfile? (y/n)      : ";

DO
   kbd$ = INKEY$
   IF LCASE$(kbd$) = "n" THEN writemethod% = 0
   IF LCASE$(kbd$) = "y" THEN writemethod% = 1
LOOP UNTIL LCASE$(kbd$) = "n" OR LCASE$(kbd$) = "y"

PRINT LCASE$(kbd$)

PRINT "Add CALL ABSOLUTE lines? (y/n) : ";

DO
   kbd$ = INKEY$
   IF LCASE$(kbd$) = "n" THEN callabs% = 0
   IF LCASE$(kbd$) = "y" THEN callabs% = 1
LOOP UNTIL LCASE$(kbd$) = "n" OR LCASE$(kbd$) = "y"

PRINT LCASE$(kbd$)

PRINT

' -------------------------------------------------------------------------- '
' Warn the user if the BASIC destination file is a QuickBASIC binary file:   '
' -------------------------------------------------------------------------- '

IF writemethod% = 1 THEN
 DIM readstring AS STRING * 3

 OPEN destfilename$ FOR BINARY AS #1
 GET #1, , readstring

 IF readstring = CHR$(252) + CHR$(0) + CHR$(1) THEN
  PRINT "BASIC destination file is probably a QuickBASIC binary file"
  PRINT "Continue anyway? (y/n)         : "
 
  DO
     kbd$ = INKEY$
     IF UCASE$(kbd$) = "N" THEN END
  LOOP UNTIL UCASE$(kbd$) = "Y"
 END IF
 
 CLOSE #1
END IF

' -------------------------------------------------------------------------- '
' Get rid of blank lines, comments and double instructions in sourcefile:    '
' -------------------------------------------------------------------------- '

conversiontime! = TIMER

PRINT "Modifying source file..."

OPEN sourcefilename$ FOR INPUT AS #1
OPEN tempfile1$ FOR OUTPUT AS #2

DO
   LINE INPUT #1, readline$

   sourceline$ = sourceline$ + UCASE$(readline$)
 
   IF INSTR(sourceline$, ";") THEN
    sourceline$ = LEFT$(sourceline$, INSTR(sourceline$, ";") - 1)
   END IF

   sourceline$ = LTRIM$(RTRIM$(sourceline$))

   IF INSTR(sourceline$, "REPE") THEN
    PRINT #2, LEFT$(sourceline$, INSTR(sourceline$, "REPE") + 2) + "Z"
    sourceline$ = RIGHT$(sourceline$, LEN(sourceline$) - INSTR(sourceline$, "REPE") - 3)
    sourceline$ = LTRIM$(RTRIM$(sourceline$))
   ELSEIF INSTR(sourceline$, "REPZ") THEN
    PRINT #2, LEFT$(sourceline$, INSTR(sourceline$, "REPZ") + 3)
    sourceline$ = RIGHT$(sourceline$, LEN(sourceline$) - INSTR(sourceline$, "REPZ") - 3)
    sourceline$ = LTRIM$(RTRIM$(sourceline$))
   ELSEIF INSTR(sourceline$, "REP") THEN
    PRINT #2, LEFT$(sourceline$, INSTR(sourceline$, "REP") + 2) + "Z"
    sourceline$ = RIGHT$(sourceline$, LEN(sourceline$) - INSTR(sourceline$, "REP") - 2)
    sourceline$ = LTRIM$(RTRIM$(sourceline$))
   END IF

   IF RIGHT$(sourceline$, 1) <> ":" THEN
    IF LEN(sourceline$) > 0 THEN PRINT #2, sourceline$
    sourceline$ = ""
   END IF

LOOP UNTIL EOF(1)

CLOSE #2
CLOSE #1

' -------------------------------------------------------------------------- '
' Insert DEBUG instructions and Assembly source code into tempfile and take  '
' care of lables:                                                            '
' -------------------------------------------------------------------------- '

OPEN tempfile1$ FOR INPUT AS #1
OPEN tempfile2$ FOR OUTPUT AS #2

DO
   LINE INPUT #1, sourceline$

   IF INSTR(sourceline$, ":") THEN
    numlabels% = numlabels% + 1
    label(numlabels%).labelname = LEFT$(sourceline$, INSTR(sourceline$, ":") - 1)
    sourceline$ = MID$(sourceline$, INSTR(sourceline$, ":") + 1)
    label(numlabels%).labelnum = linecounter%
   END IF

   sourceline$ = LTRIM$(RTRIM$(sourceline$))
   PRINT #2, sourceline$

   linecounter% = linecounter% + 1
LOOP UNTIL EOF(1)

CLOSE #2
CLOSE #1

OPEN tempfile2$ FOR INPUT AS #1
OPEN tempfile3$ FOR OUTPUT AS #2

PRINT #2, "a"

DO
   LINE INPUT #1, sourceline$

   FOR labelscan% = 1 TO numlabels%
      IF INSTR(sourceline$, LTRIM$(RTRIM$(label(labelscan%).labelname))) THEN
       sourceline$ = LEFT$(sourceline$, INSTR(sourceline$, LTRIM$(RTRIM$(label(labelscan%).labelname))) - 1) + "100"
      END IF
   NEXT labelscan%

   PRINT #2, sourceline$
LOOP UNTIL EOF(1)

CLOSE #1

PRINT #2, ""
PRINT #2, "u 100, 100"
PRINT #2, "q"

CLOSE #2

' -------------------------------------------------------------------------- '
' Run DEBUG to find machine language code length in bytes and then update    '
' the tempfile with the correct byte length:                                 '
' All errors detected will be written to the file specified in errorfile$    '
' -------------------------------------------------------------------------- '

PRINT "Detecting machine language code length..."

SHELL rundebug$ + " <" + tempfile3$ + " >" + tempfile5$

PRINT "return from shell"

OPEN tempfile5$ FOR INPUT AS #1
OPEN errorfile$ FOR OUTPUT AS #2

linecounter% = 0

DO
   oldline$ = midline$
   midline$ = newline$
   LINE INPUT #1, newline$
   SEEK #1, SEEK(1) + 2
   IF INSTR(newline$, "^") THEN
    PRINT
    PRINT "Error in line"; RTRIM$(STR$(linecounter% - 1)); ":"
    PRINT midline$
    PRINT newline$
    PRINT #2, "Error in line"; RTRIM$(STR$(linecounter% - 1)); ":"
    PRINT #2, midline$
    PRINT #2, newline$
    errorcounter% = errorcounter% + 1
    linecounter% = linecounter% - 1
   END IF
   linecounter% = linecounter% + 1
LOOP UNTIL newline$ = "-u 100, 100"

CLOSE #2
CLOSE #1

IF errorcounter% > 0 THEN
 KILL tempfile1$
 KILL tempfile2$
 KILL tempfile3$
 KILL tempfile5$
 PRINT
 PRINT "Error(s) in source code detected. Look in "; errorfile$; " for information."
 END
END IF

asmlength$ = MID$(oldline$, INSTR(oldline$, ":") + 1, 4)

PRINT "Source code byte length detected."

OPEN tempfile5$ FOR INPUT AS #1
OPEN tempfile4$ FOR OUTPUT AS #2

SEEK #1, SEEK(1) + 5

PRINT #2, "a"

DO
   LINE INPUT #1, sourceline$
   SEEK #1, SEEK(1) + 2
   sourceline$ = RIGHT$(sourceline$, LEN(sourceline$) - 10)
   IF LEN(sourceline$) > 0 THEN PRINT #2, sourceline$
LOOP UNTIL sourceline$ = ""

CLOSE #1

PRINT #2, ""
PRINT #2, "u 100, "; asmlength$
PRINT #2, "q"

CLOSE #2

' -------------------------------------------------------------------------- '
' Run DEBUG again to create a full output file:                              '
' -------------------------------------------------------------------------- '

SHELL rundebug$ + " <" + tempfile4$ + " >" + tempfile3$

' -------------------------------------------------------------------------- '
' Scan through DEBUG output file to get the byte offsets for the lines with  '
' labels in the sourcefile:                                                  '
' -------------------------------------------------------------------------- '

OPEN tempfile3$ FOR INPUT AS #1

DO
   LINE INPUT #1, readline$
LOOP UNTIL INSTR(readline$, "-u 100,")

SEEK #1, SEEK(1) + 2

labelcounter% = 1
linecounter% = 1

DO
   LINE INPUT #1, readline$
   IF label(labelcounter%).labelnum = linecounter% THEN
    label(labelcounter%).labelpos = MID$(readline$, 6, 4)
    labelcounter% = labelcounter% + 1
   END IF
   linecounter% = linecounter% + 1
LOOP UNTIL readline$ = "-q"
 
CLOSE #1

' -------------------------------------------------------------------------- '
' Update tempfile with the correct byte offset numbers for lines with labels '
' in the sourcefile:                                                         '
' -------------------------------------------------------------------------- '

OPEN tempfile2$ FOR INPUT AS #1
OPEN tempfile3$ FOR OUTPUT AS #2

PRINT #2, "a"

DO
   LINE INPUT #1, sourceline$
   FOR labelscan% = 1 TO numlabels%
      IF INSTR(sourceline$, LTRIM$(RTRIM$(label(labelscan%).labelname))) THEN
       sourceline$ = LEFT$(sourceline$, INSTR(sourceline$, LTRIM$(RTRIM$(label(labelscan%).labelname))) - 1) + label(labelscan%).labelpos
      END IF
   NEXT labelscan%
   PRINT #2, sourceline$
LOOP UNTIL EOF(1)

CLOSE #1

PRINT #2, ""
PRINT #2, "u 100, "; asmlength$
PRINT #2, "q"

CLOSE #2

PRINT "Label conversion completed."

' -------------------------------------------------------------------------- '
' Make a final pass through DEBUG to create final output file:               '
' -------------------------------------------------------------------------- '

SHELL rundebug$ + " <" + tempfile3$ + " >" + tempfile5$

PRINT "DEBUG output file successfully created."

' -------------------------------------------------------------------------- '
' Calculate the longest possible BASIC string declaration line:              '
' -------------------------------------------------------------------------- '
linecounter% = 1
longestline% = 0
maxsourcelength% = 0
maxcodelength% = 0

OPEN tempfile5$ FOR INPUT AS #1

DO
   LINE INPUT #1, readline$
LOOP UNTIL INSTR(readline$, "-u 100,")

SEEK #1, SEEK(1) + 2

DO
   LINE INPUT #1, readline$

   linelength% = LEN(RTRIM$(MID$(readline$, 11, 14)))

   IF linelength% >= longestline% THEN
    codelength% = 0
    FOR findcodelength% = 1 TO linelength% STEP 2
       IF MID$(RTRIM$(MID$(readline$, 11, 14)), findcodelength%, 1) = "0" THEN
   codelength% = codelength% + 1
       ELSE
   codelength% = codelength% + 2
       END IF
    NEXT findcodelength%
    IF maxsourcelength% < codelength% THEN maxsourcelength% = codelength%
    longestline% = linelength%
   END IF

   linecounter% = linecounter + 1
LOOP UNTIL readline$ = "-q"

maxcodelength% = LEN(codestring$) + 3 + LEN(codestring$) + (longestline% \ 2) * 11 + maxsourcelength%

CLOSE #1
' -------------------------------------------------------------------------- '
' Transform the source code to BASIC string declaration lines:               '
' -------------------------------------------------------------------------- '

FOR modifylabels% = 1 TO numlabels%
   MID$(label(modifylabels%).labelname, 2, 16) = LCASE$(RIGHT$(label(modifylabels%).labelname, 15))
NEXT modifylabels%

OPEN tempfile5$ FOR INPUT AS #1
OPEN tempfile1$ FOR INPUT AS #2

IF writemethod% = 1 THEN
 OPEN destfilename$ FOR APPEND AS #3
ELSE
 OPEN destfilename$ FOR OUTPUT AS #3
END IF

DO
   LINE INPUT #1, readline$
LOOP UNTIL INSTR(readline$, "-u 100,")

SEEK #1, SEEK(1) + 2

PRINT #3, "' ------ Created with Absolute Assembly 2.1 by Petter Holmberg, -97. ------- '"
PRINT #3, ""

PRINT #3, codestring$ + " = " + CHR$(34) + CHR$(34)

linecounter% = 1
labelcounter% = 1

DO
   LINE INPUT #1, readline$
   readline$ = RTRIM$(readline$)
   IF NOT EOF(2) THEN LINE INPUT #2, sourceline$ ELSE sourceline$ = ""

   IF readline$ <> "-q" THEN

    sourcedata$ = RTRIM$(MID$(readline$, 11, 14))
    basicline$ = codestring$ + " = " + codestring$

    FOR makebasicline% = 1 TO LEN(sourcedata$) STEP 2
       IF MID$(RTRIM$(MID$(readline$, 11, 14)), makebasicline%, 1) = "0" THEN
   basicline$ = basicline$ + " + CHR$(&H" + MID$(sourcedata$, makebasicline% + 1, 1) + ")"
       ELSE
   basicline$ = basicline$ + " + CHR$(&H" + MID$(sourcedata$, makebasicline%, 2) + ")"
       END IF
    NEXT makebasicline%

    IF LEN(basicline$) < maxcodelength% THEN basicline$ = basicline$ + SPACE$(maxcodelength% - LEN(basicline$))

    basicline$ = basicline$ + " ' "

    IF label(labelcounter%).labelnum = linecounter% THEN
     basicline$ = basicline$ + RTRIM$(label(labelcounter%).labelname) + ": "
     labelcounter% = labelcounter% + 1
    END IF

    asmline$ = (RIGHT$(readline$, (LEN(readline$) - 24)))
    IF INSTR(asmline$, CHR$(9)) THEN MID$(asmline$, INSTR(asmline$, CHR$(9))) = " "
    asmline$ = RTRIM$(asmline$)
    basicline$ = basicline$ + asmline$

    FOR labelscan% = 1 TO numlabels%
       IF INSTR(sourceline$, UCASE$(RTRIM$(label(labelscan%).labelname))) AND INSTR(sourceline$, ":") = 0 THEN
   basicline$ = LEFT$(basicline$, LEN(basicline$) - 4)
   basicline$ = basicline$ + RTRIM$(label(labelscan%).labelname)
       END IF
    NEXT labelscan%

    PRINT #3, basicline$

   END IF
 
   linecounter% = linecounter% + 1
LOOP UNTIL readline$ = "-q"

IF callabs% = 1 THEN
 PRINT #3, ""
 PRINT #3, "offset% = SADD("; codestring$; ")"
 PRINT #3, "DEF SEG = VARSEG("; codestring$; ")"
 PRINT #3, "CALL ABSOLUTE(offset%)"
 PRINT #3, "DEF SEG"
END IF

PRINT #3, ""
PRINT #3, "' ------ Created with Absolute Assembly 2.1 by Petter Holmberg, -97. ------- '"

CLOSE #3
CLOSE #2
CLOSE #1

PRINT "Source code successfully moved to BASIC destination file."

KILL tempfile1$
KILL tempfile2$
KILL tempfile3$
KILL tempfile4$
KILL tempfile5$

PRINT
PRINT "Time of conversion:"; TIMER - conversiontime!; "seconds."
PRINT

PRINT "Convert another file? (y/n)    : ";

DO
   kbd$ = INKEY$
   IF LCASE$(kbd$) = "n" THEN
    PRINT LCASE$(kbd$)
    END
   END IF
   IF LCASE$(kbd$) = "y" THEN
    PRINT LCASE$(kbd$)
    GOTO Start
   END IF
LOOP

END

' -------------------------------------------------------------------------- '
' Error handler:                                                             '
' -------------------------------------------------------------------------- '

ErrorHandler:

CLEAR
PRINT

PRINT "Whoops! An error occured during program execution."
PRINT "Check the spelling of your filenames and check the sourcefile for illegal lines."
PRINT
PRINT "Press any key to end program..."
DO: LOOP WHILE INKEY$ = ""
END

Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 24.09.2007, 14:09    Titel: Antworten mit Zitat

Soweit ich weiß, können zwar Daten im Speicher > 1 MB abgelegt werden Code kann dort aber nicht ausgeführt werden. (Mein ich vom OS-Dev noch in Erinnerung zu haben.)
_________________
Eine handvoll Glück reicht nie für zwei.
--
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 24.09.2007, 18:39    Titel: Antworten mit Zitat

Kann man eigl. auch DOS in einen Minimalzustand versetzen, um z.B ein eigenes OS auf den Speicherbereich von DOS zu schreiben oder müsste man schon versuchen dern Doskernel zu manipolieren?
_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 24.09.2007, 18:49    Titel: Antworten mit Zitat

Hm, also DOS hat keinen Speicherschutz AFAIK, also warum nicht, das könnte man wirklich als ein OS bezeichenn... und DOS wird als Bootloader missbraucht, so wie Windows 3.11 bei uns inner Schule als PXE-Loader für Windows 2000 dient (ich frag mich zwar wie die des gemacht haben, aber is ja auch wurscht happy Die haben die Mittel... und nen geilen Server, den hätt ich gern zuhause zu stehn lächeln)
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 24.09.2007, 19:43    Titel: Antworten mit Zitat

Du bist gut, auf 'nen Minimalzustand versetzen, um 'nen eigenes OS zu laden. durchgeknallt
Wenn du 'nen eigenes OS hast, wozu brauchst du dann noch DOS? (Anm.: Such doch bitte mal nach "unterschied gui fake os". mit den Augen rollen)
Des Weiteren besteht DOS so gut wie "nur" aus den Interrupt-Funktionen und die wirst du wohl oder übel brauchen, sollte es sich wie vermutet nur um ein FakeOS/GUI handeln.
_________________
Eine handvoll Glück reicht nie für zwei.
--
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
PMedia



Anmeldungsdatum: 14.08.2006
Beiträge: 2847

BeitragVerfasst am: 24.09.2007, 20:57    Titel: Antworten mit Zitat

Also ich hab des jetz so verstanden, dass wir DOS nutzen, um das System "einfach" vorzuladen... "Guck mal, mein Bootloader is größer als 100k Zunge rausstrecken" grinsen
Und danach wird DOS schlicht überschrieben, die CPU ja eh duch den Unreal-Mode zurückgesetzt. Die Interrupts kriegt man garantiert auch überschrieben / zurückgesetzt, oder? grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
AndT



Anmeldungsdatum: 02.04.2007
Beiträge: 481

BeitragVerfasst am: 24.09.2007, 21:01    Titel: Antworten mit Zitat

Stimmt.. den gleichen Fehler hat ja auch schon MS mit Win 95/98 und ME gemacht xD..
Da reichen schon züfällige Pokes mit QB um es zum Crashen zu bekommen^^.
_________________
Bis irgendwann... grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Profi-Forum Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2, 3  Weiter
Seite 1 von 3

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz