|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 10.09.2007, 22:33 Titel: 4 Gigabyte mit Quickbasic nutzen - Anwendung des Unreal Mode |
|
|
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.
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 |
|
|
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 10.09.2007, 22:49 Titel: |
|
|
Also, DAS da kenn ich als Protected Mode, aber Unreal Mode is ja auch mal ne nette Umschreibung
Jetz musst nur noch fbgfx2 portiern und schon hast fast FreeBASIC |
|
Nach oben |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
|
Nach oben |
|
|
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 16.09.2007, 15:23 Titel: |
|
|
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
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... |
|
Nach oben |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 16.09.2007, 16:00 Titel: |
|
|
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 |
|
|
Jojo alter Rang
Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 16.09.2007, 16:47 Titel: |
|
|
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 |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 16.09.2007, 17:43 Titel: |
|
|
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 |
|
|
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 21.09.2007, 22:20 Titel: |
|
|
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 |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 21.09.2007, 23:45 Titel: |
|
|
Zuerst zur Sinnfrage. 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 |
|
|
Wolfi30
Anmeldungsdatum: 17.08.2007 Beiträge: 38
|
Verfasst am: 22.09.2007, 13:37 Titel: |
|
|
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 |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 22.09.2007, 17:58 Titel: |
|
|
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.) |
|
Nach oben |
|
|
Wolfi30
Anmeldungsdatum: 17.08.2007 Beiträge: 38
|
Verfasst am: 23.09.2007, 02:37 Titel: |
|
|
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 |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 23.09.2007, 10:58 Titel: |
|
|
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, 11:12, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
Georgp24
Anmeldungsdatum: 30.06.2006 Beiträge: 81 Wohnort: Ahlen
|
Verfasst am: 23.09.2007, 11:10 Titel: |
|
|
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 |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 24.09.2007, 15:09 Titel: |
|
|
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 |
|
|
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 24.09.2007, 19:39 Titel: |
|
|
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... |
|
Nach oben |
|
|
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 24.09.2007, 19:49 Titel: |
|
|
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 Die haben die Mittel... und nen geilen Server, den hätt ich gern zuhause zu stehn ) |
|
Nach oben |
|
|
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 24.09.2007, 20:43 Titel: |
|
|
Du bist gut, auf 'nen Minimalzustand versetzen, um 'nen eigenes OS zu laden.
Wenn du 'nen eigenes OS hast, wozu brauchst du dann noch DOS? (Anm.: Such doch bitte mal nach "unterschied gui fake os". )
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 |
|
|
PMedia
Anmeldungsdatum: 14.08.2006 Beiträge: 2847
|
Verfasst am: 24.09.2007, 21:57 Titel: |
|
|
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 "
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? |
|
Nach oben |
|
|
AndT
Anmeldungsdatum: 02.04.2007 Beiträge: 481
|
Verfasst am: 24.09.2007, 22:01 Titel: |
|
|
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... |
|
Nach oben |
|
|
|
|
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.
|
|