home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Party 1994: Try This At Home
/
disk_image.bin
/
source
/
mythic
/
writer.asm
< prev
Wrap
Assembly Source File
|
1994-08-26
|
59KB
|
3,222 lines
; (C)93 xToto
TITLE 'Mythic-Writer V1.10'
PAGE 66, 132
P286
MODEL SMALL
INCLUDE INCLUDE\BIOS.INC
INCLUDE INCLUDE\DOS.INC
INCLUDE INCLUDE\KEYCODES.INC
STRWARN EQU KBLF, KBCR, '$'
PRSEQUENCER = 03C4H
PRGRAPHICS = 03CEH
PRCRT = 03D4H
NO = 0
OFF = 0
YES = 1
ON = 1
ENOFF = 0
ENJUSTOFF = 1
ENON = 2
ENJUSTON = 3
CCOLOR = 256
CBASECOLOR = 3
CPATTERN = 4
MSECSPERTICK = 54945
CCHAR = 256
BOTTOMLINE = 24
LEFTCOLUMN = 0
RIGHTCOLUMN = 39
TOPLINE = 0
CCURSET = 2
CCURSOR = 16
CCURCOLUMN = 8
CCURLINE = 8
CITEM = 2
COBJECT = 8
COBJCOLUMN = 16
COBJLINE = 16
CSTAR = 200
CSTARCOLOR = 5
CBITMAP = 4
CFRAME = 2
CFX = 3
CSCRCOLUMN = 320
CSCRLINE = 200
CSTONELINE = 8
CSTONECOLUMN = 8
CEXTKEY = 128
CBCHAR = 2
CBDELAY = 2
CCURPHASE = 16
SEGGFX = 0A000H
CBATTRIBUTE = 11
CBCURBUFFER = CCURCOLUMN * CCURLINE
CBCURSOR = CCURLINE * CCURCOLUMN
CBOBJECT = COBJLINE * COBJCOLUMN
CBOBJBUFFER = CBOBJECT * COBJECT
CBOBJECTPOS = COBJECT * 2
CBPARAGRAPH = 16
CBSCRBUFFER = CSCRCOLUMN * CSCRLINE
CBSTACK = 512
CBCHARSET = CCHAR * CCURLINE
CBCOLUMN = CCURLINE * (BOTTOMLINE - TOPLINE + 1)
CBLINE = CCURCOLUMN * (RIGHTCOLUMN - LEFTCOLUMN + 1)
CBMAP = CBCOLUMN * CSCRCOLUMN
CBOBJMASK = CITEM * COBJECT * COBJLINE * COBJCOLUMN / CBITMAP
Stack CBSTACK
Data SEGMENT PUBLIC
ASSUME CS:Code, DS:Data
STREXT DB '.WRT', 0
STR286ERROR DB '286-Processor required.', STRWARN
STRVGAERROR DB 'VGA-Card required.', STRWARN
IFDEF _WRITE
STRACCESSERROR DB 'Can''t write to file.', STRWARN
STRERROR DB 'Can''t create file.', STRWARN
STRUSAGE DB 'Usage: WRITE <FileName>', STRWARN
ENDIF
IFDEF _READ
STRACCESSERROR DB 'Can''t read from file.', STRWARN
STRERROR DB 'Can''t open file.', STRWARN
STRUSAGE DB 'Usage: READ <FileName>', STRWARN
ENDIF
STRHEXNUMBERS DB '0123456789ABCDEF', 0
STRQUADNUMBERS DB '0123', 0
STRDUALNUMBERS DB '01', 0
INCLUDE INCLUDE\PALETTE.INC
INCLUDE CURSOR\CURSOR.INC
INCLUDE INCLUDE\STONE.INC
OFFSAAABFONTS = OFFSET $
INCLUDE CHAR\BIG.INC
INCLUDE CHAR\SMALL.INC
INCLUDE CHAR\TINY.INC
VGACHARS = $
DB CCHAR * CCURLINE DUP (0)
INCLUDE INCLUDE\REQUEST.INC
AAABOBJ = AABSTAR
INCLUDE OBJECT\STAR.INC
INCLUDE OBJECT\HEART.INC
OFFSAAABOBJ = 0A0H
OFFSAAABCUR = 0C8H
OFFSAABCURBUF = 0ECH
OFFSAABMBOXBUF = 0F0H
OFFSAAABOBJBUF = CSCRCOLUMN * CITEM * COBJLINE + OFFSAAABOBJ
OFFSAAABSTONE = OFFSAAABCUR + CSCRCOLUMN * CCURSET * CCURLINE
AOBJECTSEQ DB 0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0
abObjTimer DB 000H, 010H, 020H, 030H, 040H, 050H, 060H, 070H
offsCursor DW OFFSAAABCUR
offsFont DW OFFSAAABFONTS
offsPalette DW AABCOLOR
offsPattern DW AAPATTERN
IFDEF _PLAY
offsText DW OFFSET abText
ENDIF
ynInsert DB YES
ynLock DB NO
IFNDEF _WRITE
ynShowEnd DB YES
ENDIF
aenFXDefault DB ENON
DB ENON
DB ENON
aenFX = $
enStars DB ENON
enCursor DB ENON
enObjects DB ENON
AENHANCEPROC DW OFFSET EnhanceStars
DW OFFSET EnhanceCursor
DW OFFSET EnhanceObjects
AINITPROC DW OFFSET InitStars
DW OFFSET InitCursor
DW OFFSET InitObjects
ATURNOFFPROC DW OFFSET TurnOffStars
DW OFFSET TurnOffCursor
DW OFFSET TurnOffObjects
ATURNONPROC DW OFFSET TurnOnStars
DW OFFSET TurnOnCursor
DW OFFSET TurnOnObjects
AJUMPPROC DW 0
DW 0 ; !
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW OFFSET KeyBackSpace
DW 0
DW 0 ; 10
DW 0
DW 0
DW OFFSET KeyReturn
DW 0
DW 0
DW 0
DW 0
DW 0
IFDEF _WRITE
DW OFFSET ResetFile
ELSE
DW 0
ENDIF
DW OFFSET AskText ; 20
DW 0
DW 0
DW OFFSET AskInfo
DW OFFSET AskObject
DW OFFSET AskPattern
DW 0
DW 0
DW 0
DW 0
DW 0 ; 30
DW 0
DW 0
DW OFFSET AskFont
DW 0
DW OFFSET AskHelp
DW 0
DW 0
DW OFFSET KeyInsLine
DW 0
DW 0 ; 40
DW 0
DW 0
DW 0
DW OFFSET KeyDelLine
DW 0
DW OFFSET AskCursor
DW 0
DW OFFSET AskBack
DW 0
DW 0 ; 50
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW OFFSET AskHelp
DW OFFSET SwitchStars ; 60
DW OFFSET SwitchCursor
DW OFFSET SwitchSprites
DW OFFSET KeyClear
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0 ; 70
DW OFFSET KeyToLeft
DW OFFSET KeyUp
DW OFFSET KeyToUp
DW 0
DW OFFSET KeyLeft
DW 0
DW OFFSET KeyRight
DW 0
DW OFFSET KeyToRight
DW OFFSET KeyDown ; 80
DW OFFSET KeyToDown
DW OFFSET KeyInsert
DW OFFSET KeyDelete
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0 ; 90
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0 ; 100
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0 ; 110
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0 ; 120
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
; Uninitialisierte Variablen werden auf 0 gesetzt
;
offsFirstVoid = OFFSET $
BackColor DB ?
BitPlane DB ?
cRepeat DB ?
CursorNewX DW ?
CursorNewY DW ?
CursorX DW ?
CursorY DW ?
DW 2 * (CFRAME - 1) DUP (?)
Delay DW ?
iCursor DW ?
iFrame DW ?
iItem DW ?
iObject DW ?
iPhase DW ?
IFNDEF _WRITE
NextChar DW ?
ENDIF
offs DW ?
offsChar DW ?
offsFileName DW ?
offsFrame DW ?
OldRWMode DB ?
segFileName DW ?
IFDEF _PLAY
segText DW ?
ENDIF
Random DW ?
IFNDEF _PLAY
skey DW ?
ENDIF
Timer DW ?
TimerLast DW ?
XPos DW ?
YPos DW ?
DW 2 * CFRAME DUP (?)
ynError DB ?
ynFXOn DB ?
ynQuit DB ?
ynSingle DB ?
ynSkip DB ?
Char DW ?
; Koordinaten der MessageBox in Zeichen
;
MBox_Coords = MBox_Left
MBox_Left DW ?
MBox_Top DW ?
MBox_Right DW ?
MBox_Bottom DW ?
MBox_Text DW ?
aoffsItem DW COBJECT DUP (?)
aoffsMask DW COBJECT DUP (?)
aoffsObj DW COBJECT * CFRAME DUP (?)
aoffsObjNew DW COBJECT DUP (?)
abAttribBuffer DB CBATTRIBUTE DUP (?)
aaabObjMask DB CBOBJMASK DUP (?)
awStarX DW CSTAR * CFRAME DUP (?)
offsLastVoid = OFFSET $
cbVoid = offsLastVoid - offsFirstVoid
IFDEF _PLAY
dummy DB 0
IFDEF _TEST
abText DW 'H', 50
DW 'a', 50
DW 'l', 50
DW 'l', 50
DW 'o', 50
DW KBESC, 50
ELSE
abText = $
ENDIF
ENDIF
Data ENDS
Code SEGMENT PUBLIC
ASSUME CS:Code, DS:Data
; *****************************************************************************
; Holt das nächste Zeichen aus dem Speicher: C
; *****************************************************************************
IFDEF _PLAY
AccessFile PROC
push si
push es
push ax
mov si, offsText
mov es, segText
mov ax, es:[si]
mov NextChar, ax
mov ax, es:[si+CBCHAR]
mov Delay, ax
add offsText, CBCHAR + CBDELAY
cmp offsText, CBPARAGRAPH
jna AccessFile_Ok
sub offsText, CBPARAGRAPH
inc segText
AccessFile_Ok: mov cRepeat, CFRAME
dec Delay
clc
pop ax
pop es
pop si
ret
AccessFile ENDP
ENDIF
; *****************************************************************************
; Liest die Informationen zum nächsten Zeichen aus der Datei: C
; *****************************************************************************
IFDEF _READ
AccessFile PROC
pusha
mov ah, DOS_Read_FROM_HANDLE
mov bx, skey
mov cx, cbChar
mov dx, OFFSET NextChar
int DOS_FUNCTION
jc Access_Error
cmp ax, cbChar
jne Access_Error
; Liest die Verzügerung
;
mov ah, DOS_Read_FROM_HANDLE
mov bx, skey
mov cx, cbDelay
mov dx, OFFSET Delay
int DOS_FUNCTION
jc Access_Error
cmp ax, cbDelay
jne Access_Error
clc
mov cRepeat, CFRAME
dec Delay
jmp Access_End
Access_Error: mov ynError, YES
stc
Access_End: popa
ret
AccessFile ENDP
ENDIF
; *****************************************************************************
; Schreibt die Informationen zum nächsten Zeichein in die Datei: C
; *****************************************************************************
IFDEF _WRITE
AccessFile PROC
pusha
call GetDelay
mov ah, DOS_WRITE_TO_HANDLE
mov bx, skey
mov cx, cbChar
mov dx, OFFSET Char
int DOS_FUNCTION
jc Access_Error
cmp ax, cbChar
jne Access_Error
; Schreibt die Verzügerung
;
mov ah, DOS_WRITE_TO_HANDLE
mov bx, skey
mov cx, cbDelay
mov dx, OFFSET Delay
int DOS_FUNCTION
jc Access_Error
cmp ax, cbDelay
jne Access_Error
jmp Access_End
Access_Error: mov ynError, YES
stc
Access_End: popa
ret
AccessFile ENDP
ENDIF
ActualizeCursor PROC
push ax
push si
mov si, iFrame
shl si, 2
add si, OFFSET CursorX
mov ax, CursorNewX
mov ds:[si], ax
mov ax, CursorNewY
mov ds:[si+2], ax
pop si
pop ax
ret
ActualizeCursor ENDP
; *****************************************************************************
; Dialogboxen auf dem Bildschirm darstellen
; *****************************************************************************
AskBack PROC
pusha
mov si, OFFSET BACKREQUESTER
call MessageBox
jc AskBack_End
call UpCase
mov ax, Char
mov di, OFFSET STRHEXNUMBERS
call Pos
jc AskBack_End
mov si, OFFSET ABACKCOLOR
add si, cx
mov al, ds:[si]
mov BackColor, al
AskBack_End: popa
ret
AskBack ENDP
AskCursor PROC
pusha
mov si, OFFSET CURSORREQUESTER
call MessageBox
jc AskCursor_End
mov ax, Char
mov di, OFFSET STRDUALNUMBERS
call Pos
jc AskCursor_End
mov iCursor, cx
mov ax, cx
mov dx, CCURLINE * CSCRCOLUMN
mul dx
add ax, OFFSAAABCUR
mov offsCursor, ax
AskCursor_End: popa
ret
AskCursor ENDP
IFNDEF _WRITE
AskEnd PROC
push ax
push si
mov ynLock, YES
AskEnd_Wait: call ExpectRetrace
call ExpectPicture
call SwitchFrame
call TurnOffFX
mov ax, 1
call EnhanceTimer
cmp ynShowEnd, YES
jne AskEnd_NoShow
cmp iFrame, 0
jne AskEnd_NoShow
mov si, OFFSET ENDREQUESTER
call MessageBox
mov ynShowEnd, NO
AskEnd_NoShow: call TurnOnFX
call GetKey
jc AskEnd_Wait
pop si
pop ax
ret
AskEnd ENDP
ENDIF
AskFont PROC
pusha
mov si, OFFSET FONTREQUESTER
call MessageBox
jc AskFont_End
mov ax, Char
mov di, OFFSET STRQUADNUMBERS
call Pos
jc AskFont_End
shl cx, 11
add cx, OFFSAAABFONTS
mov offsFont, cx
AskFont_End: popa
ret
AskFont ENDP
AskText PROC
pusha
mov si, OFFSET FRONTREQUESTER
call MessageBox
jc AskText_End
mov ax, Char
mov di, OFFSET STRHEXNUMBERS
call Pos
jc AskText_End
shl cx, 4
add cx, OFFSET AABCOLOR
mov offsPalette, cx
AskText_End: popa
ret
AskText ENDP
AskHelp PROC
push si
mov si, OFFSET HELP1REQUESTER
call MessageBox
mov si, OFFSET HELP2REQUESTER
call MessageBox
pop si
ret
AskHelp ENDP
AskInfo PROC
push si
mov si, OFFSET INFOREQUESTER
call MessageBox
pop si
ret
AskInfo ENDP
AskObject PROC
pusha
mov si, OFFSET OBJECTREQUESTER
call MessageBox
jc AskObject_End
mov ax, Char
mov di, OFFSET STRDUALNUMBERS
call Pos
jc AskObject_End
mov iItem, cx
AskObject_End: popa
ret
AskObject ENDP
AskPattern PROC
pusha
mov si, OFFSET PATTERNREQUESTER
call MessageBox
mov ax, Char
mov di, OFFSET STRQUADNUMBERS
call Pos
jc AskPattern_End
shl cx, 6
add cx, OFFSET AAPATTERN
mov offsPattern, cx
AskPattern_End: popa
ret
AskPattern ENDP
ClearLatches PROC
push ds
push si
mov ax, SEGGFX
mov ds, ax
mov si, CSCRLINE * CSCRCOLUMN
lodsb
pop si
pop ds
ret
ClearLatches ENDP
; *****************************************************************************
; Schließt die Textdatei
; *****************************************************************************
IFNDEF _PLAY
CloseFile PROC
push ax
push bx
mov ah, DOS_CLOSE_FILE
mov bx, skey
int DOS_FUNCTION
pop bx
pop ax
ret
CloseFile ENDP
ENDIF
; *****************************************************************************
; Konvertiert die Objekte in das Video-Format
; *****************************************************************************
Convert PROC
pusha
mov bp, sp
add bp, 012H
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
inc dx
mov al, 001H
mov bx, ss:[bp]
mov si, ss:[bp+2]
mov di, ss:[bp+4]
mov cx, ss:[bp+6]
Convert_NextLn: push cx
mov cx, ss:[bp+8]
Convert_NextCl: out dx, al
mov ah, ds:[si]
mov es:[di], ah
or ah, ah
je Convert_Blank
mov ah, 0FFH
mov ds:[si], ah
Convert_Blank: inc si
add al, al
cmp al, 010H
jne Convert_Next
inc di
mov al, 001H
Convert_Next: loop Convert_NextCl
pop cx
sub di, bx
add di, CSCRCOLUMN
loop Convert_NextLn
popa
ret 10
Convert ENDP
ConvertChars PROC
pusha
mov bp, OFFSET ABCPHASE
mov ax, CCURCOLUMN
mov dx, CCURLINE
mov di, OFFSAAABCUR
mov si, OFFSET AAAABCURSOR
mov bx, CCURCOLUMN / CBITMAP
mov cx, CCURSET + 1
ConvChr_NextIt: push cx
xor ch, ch
mov cl, ds:[bp]
ConvChr_Next: push ax
push dx
push di
push si
push bx
call Convert
add si, CBCURSOR
add di, CCURCOLUMN / CBITMAP
loop ConvChr_Next
mov cl, ds:[bp]
shl cl, 1
sub di, cx
add di, CSCRCOLUMN * CCURLINE
inc bp
pop cx
loop ConvChr_NextIt
popa
ret
ConvertChars ENDP
ConvertObjects PROC
pusha
mov ax, COBJCOLUMN
mov dx, COBJLINE
mov di, OFFSAAABOBJ
mov si, OFFSET AAABOBJ
mov bx, COBJCOLUMN / CBITMAP
mov cx, CITEM
ConvObj_NextIt: push cx
mov cx, COBJECT
ConvObj_Next: push ax
push dx
push di
push si
push bx
call Convert
add si, CBOBJECT
add di, COBJCOLUMN / CBITMAP
loop ConvObj_Next
pop cx
add di, CSCRCOLUMN * COBJLINE - COBJCOLUMN * 2
loop ConvObj_NextIt
; Bitmasken anlegen
;
mov si, OFFSET AAABOBJ
mov di, OFFSET aaabObjMask
push es
push ds
pop es
mov cx, CBOBJMASK
ConvObj_NextMsk:push cx
xor ah, ah
mov cx, CBITMAP
ConvObj_NextBit:shr ah, 1
lodsb
or al, al
je ConvObj_Void
or ah, 008H
ConvObj_Void: loop ConvObj_NextBit
mov al, ah
stosb
pop cx
loop ConvObj_NextMsk
pop es
popa
ret
ConvertObjects ENDP
; *****************************************************************************
; Schaltet die Rahmenfarbe auf Schwarz
; *****************************************************************************
IFDEF _TEST
DarkBorder PROC
push ax
push dx
mov dx, 003C0H
mov al, 031H
out dx, al
mov al, 000H
out dx, al
pop dx
pop ax
ret
DarkBorder ENDP
ENDIF
; *****************************************************************************
; Führt Aktionen auf dem Bildschirm aus
; *****************************************************************************
DoABC PROC
pusha
cmp ynSingle, YES
je DoABC_Single
mov ax, Char
; Kontrolle auf Ende
;
cmp ax, KBESC
jne DoABC_NotEnd
mov ynQuit, YES
jmp DoABC_End
; Kontrolle auf Rückschritt
;
DoABC_NotEnd: cmp ax, KBBS
jne DoABC_NoBS
call KeyBackSpace
jmp DoABC_End
; Kontrolle auf Zeilenvorschub
;
DoABC_NoBS: cmp ax, KBLF
je DoABC_End
cmp ax, KBCR
jne DoABC_NoCR
call KeyReturn
jmp DoABC_End
; Kontrolle aus ASCII-Textzeichen
;
DoABC_NoCR: or ah, ah
jne DoABC_Ext
call KeyABC
jmp DoABC_End
; Ansprung einer Funktion für Steuerzeichen
;
DoABC_Ext: shr ax, 7
mov si, ax
add si, OFFSET AJUMPPROC
mov bx, ds:[si]
or bx, bx
je DoABC_End
call bx
jmp DoABC_End
DoABC_Single: mov ynSingle, NO
mov ynSkip, YES
DoABC_End: dec cRepeat
call ResetCursor
call ActualizeCursor
popa
ret
DoABC ENDP
DoClear PROC
pusha
call ClearLatches
xor di, di
mov cx, CSCRLINE
DoClear_NextLn: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep stosb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoClear_NextLn
; Uhr vorstellen
;
mov ax, 2
call EnhanceTimer
popa
ret
DoClear ENDP
DoDown PROC
; Bildinhalt verschieben und neue Zeile leeren
;
pusha
std
mov si, (CSCRLINE - CCURLINE - 1) * CSCRCOLUMN + CSCRCOLUMN / CBITMAP - 1
mov di, (CSCRLINE - 1) * CSCRCOLUMN + CSCRCOLUMN / CBITMAP - 1
push ds
push es
pop ds
mov cx, CSCRLINE - CCURLINE
DoDown_NextCpy: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep movsb
sub di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
sub si, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoDown_NextCpy
pop ds
cld
call ClearLatches
xor di, di
mov cx, CCURLINE
DoDown_NextClr: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep stosb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoDown_NextClr
; Uhr vorstellen
;
mov ax, 2
call EnhanceTimer
popa
ret
DoDown ENDP
DoInsert PROC
pusha
call GetCurOffset
std
mov dx, RIGHTCOLUMN
sub dx, xPos
add dx, dx
mov si, offs
add si, (CCURLINE - 1) * CSCRCOLUMN - 1
add si, dx
mov di, si
add di, CCURCOLUMN / CBITMAP
push ds
push es
pop ds
mov cx, CCURLINE
DoIns_NextLn: push cx
mov cx, dx
rep movsb
call ClearLatches
mov cx, CCURCOLUMN / CBITMAP
rep stosb
add si, dx
sub si, CSCRCOLUMN
add di, dx
sub di, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
pop cx
loop DoIns_NextLn
cld
pop ds
popa
ret
DoInsert ENDP
DoInsLine PROC
; Bildinhalt verschieben und neue Zeile leeren
;
pusha
std
mov si, (CSCRLINE - CCURLINE - 1) * CSCRCOLUMN + CSCRCOLUMN / CBITMAP - 1
mov di, (CSCRLINE - 1) * CSCRCOLUMN + CSCRCOLUMN / CBITMAP - 1
mov cx, BOTTOMLINE
sub cx, yPos
push ds
push es
pop ds
je DoInsL_Bottom
shl cx, 3
DoInsL_NextCpy: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep movsb
sub di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
sub si, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoInsL_NextCpy
DoInsL_Bottom: pop ds
cld
call ClearLatches
mov di, si
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP + 1
mov cx, CCURLINE
DoInsL_NextClr: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep stosb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoInsL_NextClr
; Uhr vorstellen
;
mov ax, 2
call EnhanceTimer
popa
ret
DoInsLine ENDP
DoUp PROC
; Bildinhalt verschieben und neue Zeile leeren
;
pusha
mov si, CCURLINE * CSCRCOLUMN
xor di, di
push ds
push es
pop ds
mov cx, CSCRLINE - CCURLINE
DoUp_NextCpy: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep movsb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
add si, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoUp_NextCpy
pop ds
call ClearLatches
mov cx, CCURLINE
DoUp_NextClr: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep stosb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoUp_NextClr
; Uhr vorstellen
;
mov ax, 2
call EnhanceTimer
popa
ret
DoUp ENDP
DoZipChar PROC
pusha
call GetCurOffset
mov dx, RIGHTCOLUMN
sub dx, xPos
add dx, dx
mov si, offs
add si, CCURCOLUMN / CBITMAP
mov di, offs
push ds
push es
pop ds
mov cx, CCURLINE
DoZipChar_Next: push cx
mov cx, dx
rep movsb
call ClearLatches
mov cx, CCURCOLUMN / CBITMAP
rep stosb
sub si, dx
add si, CSCRCOLUMN
sub di, dx
add di, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
pop cx
loop DoZipChar_Next
pop ds
popa
ret
DoZipChar ENDP
DoZipLine PROC
; Bildinhalt verschieben und neue Zeile leeren
;
pusha
mov ax, yPos
mov dx, CSCRCOLUMN * CCURLINE
mul dx
mov di, ax
mov si, ax
add si, CSCRCOLUMN * CCURLINE
mov cx, BOTTOMLINE
sub cx, yPos
push ds
push es
pop ds
je DoZipL_Bottom
shl cx, 3
DoZipL_NextCpy: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep movsb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
add si, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoZipL_NextCpy
DoZipL_Bottom: pop ds
call ClearLatches
mov cx, CCURLINE
DoZipL_NextClr: push cx
mov cx, CSCRCOLUMN / CBITMAP
rep stosb
add di, (CSCRCOLUMN * (CBITMAP - 1)) / CBITMAP
pop cx
loop DoZipL_NextClr
; Uhr vorstellen
;
mov ax, 2
call EnhanceTimer
popa
ret
DoZipLine ENDP
; *****************************************************************************
; Stellt den alten Video-Modus wieder her
; *****************************************************************************
Done PROC
pusha
mov ah, VIDEO_SET_MODE
mov al, VIDEO_80x25x16
int VIDEO_FUNCTION
IFNDEF _PLAY
cmp ynError, YES
jne Done_OK
IFDEF _READ
cmp NextChar, KBESC
je Done_OK
ENDIF
mov dx, OFFSET STRACCESSERROR
mov ah, DOS_WRITE_STRING
int DOS_FUNCTION
stc
jmp Done_End
ENDIF
Done_OK: clc
Done_End: popa
ret
Done ENDP
DoneBlit PROC
push dx
push ax
mov al, OldRWMode
mov ah, 005H
xchg al, ah
mov dx, PRGRAPHICS
out dx, ax
pop ax
pop dx
ret
DoneBlit ENDP
; *****************************************************************************
; Zeichnet den Block ax ab der Adresse es:di
; *****************************************************************************
DrawBlock PROC
; Anfangsadresse des Steins bestimmen
;
pusha
mov si, OFFSAAABSTONE
add si, ax
add si, ax
push ds
mov ax, SEGGFX
mov ds, ax
mov cx, CSTONELINE
DBlock_NextLn: push cx
mov cx, CSTONECOLUMN / CBITMAP
rep movsb
add di, CSCRCOLUMN - CSTONECOLUMN / CBITMAP
add si, CSCRCOLUMN - CSTONECOLUMN / CBITMAP
pop cx
loop DBlock_NextLn
pop ds
popa
ret
DrawBlock ENDP
EnhanceTimer PROC
pusha
add Timer, ax
; Effekte weiterstellen
;
mov si, OFFSET AENHANCEPROC
mov di, OFFSET aenFX
mov cx, CFX
EnhanceTimer_FX:mov dl, ds:[di]
inc dl
and dl, 3
cmp dl, ENON
jl EnhanceTimer_No
mov bx, ds:[si]
call bx
EnhanceTimer_No:inc di
add si, 2
loop EnhanceTimer_FX
popa
ret
EnhanceTimer ENDP
EnhanceCursor PROC
pusha
add iPhase, ax
mov si, iCursor
add si, OFFSET ABCPHASE
xor dh, dh
mov dl, ds:[si]
shl dx, 2
cmp iPhase, dx
jnae EnhCur_End
sub iPhase, dx
EnhCur_End: popa
ret
EnhanceCursor ENDP
EnhanceObjects PROC
pusha
cmp enObjects, ENON
jl EnhObj_End
mov si, OFFSET abObjTimer
mov cx, COBJECT
EnhanceTm_Obj: add ds:[si], al
inc si
loop EnhanceTm_Obj
EnhObj_End: popa
ret
EnhanceObjects ENDP
EnhanceStars PROC
pusha
mov si, OFFSET awStarX
cmp iFrame, 0
je EnhStars_Frm0
add si, CSTAR * 2
EnhStars_Frm0: mov cx, CSTAR
EnhStars_Next: mov ax, ds:[si]
mov dx, cx
and dx, 3
inc dx
sub ax, dx
jns EnhStars_Ok
add ax, CSCRCOLUMN
EnhStars_Ok: mov ds:[si], ax
add si, 2
loop EnhStars_Next
popa
ret
EnhanceStars ENDP
; *****************************************************************************
; Auf Rasterstrahlpositionen warten
; *****************************************************************************
ExpectPicture PROC
push dx
push ax
mov dx, 003DAH
Ray_OutFrame: in ax, dx
and ax, 00008H
cmp ax, 00000H
jne Ray_OutFrame
pop ax
pop dx
ret
ExpectPicture ENDP
ExpectRetrace PROC
pusha
; Bildanfangsadresse bestimmen
;
mov dx, PRCRT
mov al, 00DH
out dx, al
inc dx
mov ax, offsFrame
out dx, al
; Auf Rücklauf warten
;
IFDEF _TEST
call DarkBorder
ENDIF
mov dx, 003DAH
Ray_InFrame: in ax, dx
and ax, 00008H
cmp ax, 00008H
jne Ray_InFrame
IFDEF _TEST
call WhiteBorder
ENDIF
popa
ret
ExpectRetrace ENDP
; *****************************************************************************
; Bestimmt die Bildschiradresse der oberen linken Cursor-Ecke: Offs
; *****************************************************************************
GetCurOffset PROC
pusha
mov si, iFrame
shl si, 2
add si, OFFSET CursorX
mov ax, ds:[si+2]
mov dx, CCURLINE * CSCRCOLUMN
mul dx
mov dx, ds:[si]
add ax, dx
add ax, dx
mov offs, ax
popa
ret
GetCurOffset ENDP
; ****************************************************************************
; Bestimmt die Zeit zwischen zwei Tastendrücken: Delay
; ****************************************************************************
GetDelay PROC
push ax
mov ax, Timer
sub ax, TimerLast
mov Delay, ax
mov ax, Timer
mov TimerLast, ax
pop ax
ret
GetDelay ENDP
IFNDEF _PLAY
GetFile PROC
pusha
; Kontrolle, ob Dateiname angegeben ist
;
mov segFileName, es
mov di, 080H
mov al, es:[di]
or al, al
je GetFile_Error
; 0zeichen einfügen
;
GetFile_Ok1: xor ah, ah
inc di
mov si, di
add di, ax
mov es:[di], ah
; Führende Leerzeichen überspringen
;
mov di, si
mov cx, ax
mov bx, ax
mov al, ' '
inc cx
repe scasb
or cx, cx
je GetFile_Error
GetFile_Ok2: dec di
mov offsFileName, di
; Aus Option untersuchen
;
mov al, es:[di]
cmp al, '0'
jl GetFile_Error
; Endung suchen
;
mov di, si
mov cx, bx
mov al, '.'
repne scasb
or cx, cx
jne GetFile_Ok
; Endung .WRT anfügen
;
mov si, OFFSET STREXT
mov cx, 5
rep movsb
GetFile_Ok: clc
GetFile_End: popa
ret
; Zeigt die Syntax ax
;
GetFile_Error: mov dx, OFFSET STRUSAGE
mov ah, DOS_WRITE_STRING
int 021H
stc
jmp GetFile_End
GetFile ENDP
ENDIF
IFDEF _WRITE
; ****************************************************************************
; Liest ein Zeichen von der Tastatur: Char, C
; ****************************************************************************
GetKey PROC
; Kontrolle, ob ein Zeichen vorliegt
;
push ax
mov ah, KEYBOARD_GET_STATUS
int KEYBOARD_FUNCTION
jz GKey_None
; Vorhandenes Zeichen einlesen
;
mov ah, KEYBOARD_READ_CHAR
int KEYBOARD_FUNCTION
cmp al, 0
je GKey_Normal
xor ah, ah
Gkey_Normal: mov Char, ax
; Zeichen abspeichern
;
cmp ynLock, YES
je GKey_Locked
call AccessFile
GKey_Locked: clc
jmp GKey_End
GKey_None: stc
GKey_End: pop ax
ret
GetKey ENDP
ENDIF
; *****************************************************************************
; Liest ein Zeichen aus einer Datei oder von der Tastatur
; *****************************************************************************
IFNDEF _WRITE
GetKey PROC
push ax
cmp ynLock, YES
je GKey_Locked
; Verzögerung abwarten
;
call MakeDelay
jg GKey_None
mov ax, NextChar
call AccessFile
mov Char, ax
jmp GKey_Hit
GKey_Locked: mov ah, KEYBOARD_GET_STATUS
int KEYBOARD_FUNCTION
jz GKey_None
; Vorhandenes Zeichen einlesen
;
mov ah, KEYBOARD_READ_CHAR
int KEYBOARD_FUNCTION
GKey_Hit: clc
jmp GKey_End
GKey_None: stc
GKey_End: pop ax
ret
GetKey ENDP
ENDIF
; *****************************************************************************
; Erzeugt eine Zufallszahl: Random
; *****************************************************************************
GetRandom PROC
push ax
mov ax, Random
ror ax, 1
xor ax, Timer
not ax
add ax, 04294
xchg ah, al
mov Random, ax
pop ax
ret
GetRandom ENDP
; *****************************************************************************
; Nimmt alle nötigen Voreinstellungen vor: C
; *****************************************************************************
Init PROC
; Initialisierung der Segmentregister
;
pusha
mov ax, SEG Data
mov ds, ax
; Uninitialisierte Variablen auf 0 setzen
;
push es
push ds
pop es
mov di, offsFirstVoid
xor al, al
mov cx, cbVoid
rep stosb
pop es
IFNDEF _PLAY
call GetFile
jnc Init_OpenFile
jmp Init_End
ENDIF
; Datei öffnen
;
Init_OpenFile: call OpenFile
IFNDEF _PLAY
jnc Init_Opened
mov dx, OFFSET STRERROR
mov ah, DOS_WRITE_STRING
int 021H
stc
jmp Init_End
ENDIF
Init_Opened: cld
mov ax, SEGGFX
mov es, ax
; Bestimmung des Prozessortypes
;
xor ax, ax
push ax
popf
pushf
pop ax
and ax, 0F0H
cmp ax, 0F0H
jne Init_286OK
mov dx, OFFSET STR286ERROR
mov ah, DOS_WRITE_STRING
int DOS_FUNCTION
stc
jmp Init_End
; Bestimmung der Grafikkarte
;
Init_286OK: mov ah, VIDEO_GET_VGA
int VIDEO_FUNCTION
cmp al, VIDEO_GET_VGA
je Init_VGAOK
mov dx, OFFSET STRVGAERROR
mov ah, DOS_WRITE_STRING
int DOS_FUNCTION
stc
jmp Init_End
; VGA-Zeichensatz laden
;
Init_VGAOK: push ds
push es
mov ax, 01130H
mov bh, 003H
int VIDEO_FUNCTION
mov ax, ds
push es
pop ds
mov es, ax
mov si, bp
mov di, OFFSET VGAChars
mov cx, CCHAR * CCURLINE
rep movsb
pop es
pop ds
; Sicherung des alten Bildschirmmodus und Einschaltung des neuen
;
mov ah, VIDEO_SET_MODE
mov al, VIDEO_320x200x256
int VIDEO_FUNCTION
; Lineare Adressierung des Graphics-Controllers
;
mov dx, 003CEH
mov al, 005H
out dx, al
inc dx
in al, dx
and al, 0EFH
out dx, al
dec dx
; Lineare Adressierung des Graphics-Controllers (s.o.)
;
mov al, 006H
out dx, al
inc dx
in al, dx
and al, 0FDH
out dx, al
; Lineare Adressierung des Sequencer-Controllers
;
mov dx, PRSEQUENCER
mov al, 004H
out dx, al
inc dx
in al, dx
and al, 0F7H
or al, 4
out dx, al
; Byteweise-Adressierung des CRT-Controllers
;
mov dx, PRCRT
mov al, 014H
out dx, al
inc dx
in al, dx
and al, 0BFH
out dx, al
dec dx
; Byteweise-Adressierung des CRT-Controllers (s.o.)
;
mov al, 017H
out dx, al
inc dx
in al, dx
or al, 040H
out dx, al
; Bildschirm löschen
;
xor di, di
xor al, al
mov cx, CBMAP
rep stosb
; Initialisierung der 256 Farben
;
push es
push ds
pop es
mov dx, OFFSET AAPALETTE
mov ah, VIDEO_DACS
mov al, VIDEO_SET_DACS
xor bx, bx
mov cx, CCOLOR
int VIDEO_FUNCTION
pop es
; Alle Bitplanes für Zugriff einschalten
;
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
inc dx
mov al, 00FH
out dx, al
; Zeilen-Abstand bestimmen
;
mov dx, PRCRT
mov al, 013H
out dx, al
inc dx
mov al, CSCRCOLUMN / 2
out dx, al
; Effekte initialisieren
;
mov si, OFFSET AINITPROC
mov cx, CFX
Init_NextFX: mov bx, ds:[si]
call bx
add si, 2
loop Init_NextFX
call InitBlit
call TurnOnFX
call SwitchFrame
call TurnOnFX
call SwitchFrame
clc
Init_End: popa
ret
Init ENDP
InitBlit PROC
push dx
push ax
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
inc dx
mov al, 00FH
out dx, al
mov dx, PRGRAPHICS
mov al, 005H
out dx, al
inc dx
in al, dx
mov OldRWMode, al
and al, not 3
or al, 1
out dx, al
pop ax
pop dx
ret
InitBlit ENDP
; *****************************************************************************
; Cursor initialisieren
; *****************************************************************************
InitCursor PROC
call ConvertChars
ret
InitCursor ENDP
; *****************************************************************************
; Sprites initialisieren
; *****************************************************************************
InitObjects PROC
push cx
call ConvertObjects
xor cx, cx
InitObjects_Nx: mov iObject, cx
call MoveObject
inc cx
cmp cx, COBJECT
jl InitObjects_Nx
pop cx
ret
InitObjects ENDP
; *****************************************************************************
; Sterne initialisieren
; *****************************************************************************
InitStars PROC
pusha
mov si, OFFSET awStarX
mov di, si
add di, CSTAR * 2
mov cx, CSTAR
InitStars_Next: call GetRandom
mov dx, Random
mov ax, CSCRCOLUMN
mul dx
mov ds:[si], dx
mov ax, cx
and ax, 3
inc ax
shr ax, 1
add dx, ax
mov ds:[di], dx
add si, 2
add di, 2
loop InitStars_Next
popa
ret
InitStars ENDP
; *****************************************************************************
; Funktionen zur Ausgabe von Tasten
; *****************************************************************************
KeyABC PROC
call GetCurOffset
cmp ynInsert, YES
jne KeyABC_NoIns
call DoInsert
KeyABC_NoIns: call MoveRight
pushf
call DoneBlit
call Print
call InitBlit
popf
jnc KeyABC_End
call DoUp
KeyABC_End: ret
KeyABC ENDP
KeyBackSpace PROC
call MoveLeft
jnc KeyLeft_Del
call DoDown
KeyLeft_Del: call ResetCursor
call ActualizeCursor
call DoZipChar
ret
KeyBackSpace ENDP
KeyDelete PROC
call DoZipChar
ret
KeyDelete ENDP
KeyDelLine PROC
call DoZipLine
ret
KeyDelLine ENDP
KeyDown PROC
call MoveDown
jnc KeyDown_End
call DoUp
KeyDown_End: ret
KeyDown ENDP
KeyInsert PROC
cmp iFrame, 0
jne KeyInsert_End
xor ynInsert, YES
KeyInsert_End: ret
KeyInsert ENDP
KeyInsLine PROC
call DoInsLine
ret
KeyInsLine ENDP
KeyClear PROC
call DoClear
ret
KeyClear ENDP
KeyLeft PROC
call MoveLeft
jnc KeyLeft_End
call DoDown
KeyLeft_End: ret
KeyLeft ENDP
KeyReturn PROC
call MoveToNextLine
jnc KeyReturn_End
call DoUp
KeyReturn_End: ret
KeyReturn ENDP
KeyRight PROC
call MoveRight
jnc KeyRight_End
call DoUp
KeyRight_End: ret
KeyRight ENDP
KeyToDown PROC
call MoveToBottom
ret
KeyToDown ENDP
KeyToLeft PROC
call MoveToLeft
ret
KeyToLeft ENDP
KeyToRight PROC
call MoveToRight
ret
KeyToRight ENDP
KeyToUp PROC
call MoveToTop
ret
KeyToUp ENDP
KeyUp PROC
call MoveUp
jnc KeyDown_End
call DoDown
KeyUp_End: ret
KeyUp ENDP
; ****************************************************************************
; Stellt die Bildattribute wieder her
; ****************************************************************************
LoadAttributes PROC
push es
push si
push di
mov si, OFFSET abAttribBuffer
mov di, OFFSET CursorX
push ds
pop es
movsw
movsw
mov di, OFFSET BackColor
movsb
mov di, OFFSET offsPalette
movsw
mov di, OFFSET offsPattern
movsw
mov di, OFFSET offsFont
movsw
pop di
pop si
pop es
ret
LoadAttributes ENDP
; *****************************************************************************
; Hauptprogramm
; *****************************************************************************
Main PROC
call Init
jc Main_Error1
call Run
IFNDEF _PLAY
call CloseFile
ENDIF
call Done
Main_Error1: mov al, 0
adc al, al
mov ah, DOS_TERMINATE_EXE
int DOS_FUNCTION
Main ENDP
; ****************************************************************************
; Bestimmt, ob wieder ein Tastendruck kommt
; ****************************************************************************
MakeDelay PROC
push ax
; Kontrolle, ob eine Taste gedrückt wird
;
mov ah, KEYBOARD_GET_STATUS
int KEYBOARD_FUNCTION
je MakeDelay_OK
mov ah, KEYBOARD_READ_CHAR
int KEYBOARD_FUNCTION
cmp al, KBESC
jne MakeDelay_GoOn
mov ynQuit, YES
MakeDelay_GoOn: mov ax, 00001H
mov Delay, ax
MakeDelay_OK: dec Delay
cmp Delay, 0
pop ax
ret
MakeDelay ENDP
; *****************************************************************************
; Zeichnet einen Kasten auf den Bildschirm < ds:si
; *****************************************************************************
MessageBox PROC
pusha
call TurnOnFX
; Koordinaten der Box und Text bestimmen
;
MBox_Draw: mov di, OFFSET MBox_Coords
push es
push ds
pop es
mov cx, 4
rep movsw
pop es
mov MBox_Text, si
; Startadresse des Hintergrundes bestimmen: ds:si
;
mov ax, MBox_Top
shl ax, 3
mov dx, CSCRCOLUMN
mul dx
mov dx, MBox_Left
shl dx, 1
add ax, dx
mov si, ax
; Startadresses der Puffers bestimmen
mov di, OFFSAABMBOXBUF
; Zahl der Bildschirmzeilen bestimmen
;
mov cx, MBox_Bottom
sub cx, MBox_Top
inc cx
shl cx, 3
; Zahl der Bildschirmspalten bestimmen
;
mov bx, MBox_Right
sub bx, MBox_Left
inc bx
shl bx, 1
; Daten zum Zurücklesen sichern
;
push bx
push cx
push si
; Hintergrund kopieren
;
push es
push ds
push es
pop ds
mov ax, SEGGFX
mov es, ax
MBox_SNextLn: push cx
mov cx, bx
rep movsb
add si, CSCRCOLUMN
sub si, bx
add di, CSCRCOLUMN
sub di, bx
pop cx
loop MBox_SNextLn
pop ds
pop es
; Obere Kante zeichnen
;
pop di
push di
push di
mov ax, ISTONETOPLEFT
call DrawBlock
add di, CCURCOLUMN / CBITMAP
mov cx, MBox_Right
sub cx, MBox_Left
dec cx
push cx
mov ax, ISTONEHORIZONTAL
MBox_TopLn: call DrawBlock
add di, CCURCOLUMN / CBITMAP
loop MBox_TopLn
mov ax, ISTONETOPRIGHT
call DrawBlock
; Mittleren Bereich zeichnen
;
pop cx
inc cx
shl cx, 1
push cx
mov cx, MBox_Bottom
sub cx, MBox_Top
dec cx
MBox_NextLn: mov bx, cx
pop cx
pop di
add di, CSCRCOLUMN * CSTONELINE
push di
push cx
mov ax, ISTONEVERTICAL
call DrawBlock
add di, cx
call DrawBlock
mov cx, bx
loop MBox_NextLn
; Untere Kante zeichnen
;
pop cx
shr cx, 1
dec cx
pop di
add di, CSCRCOLUMN * CSTONELINE
mov ax, ISTONEBOTTOMLEFT
call DrawBlock
mov ax, ISTONEHORIZONTAL
MBox_BottomLn: add di, CCURCOLUMN / CBITMAP
call DrawBlock
loop MBox_BottomLn
add di, CCURCOLUMN / CBITMAP
mov ax, ISTONEBOTTOMRIGHT
call DrawBlock
; Hintergrund wiederherstellen
;
call Write
call WaitKey
mov ynSingle, YES
mov ynSkip, YES
mov si, OFFSAABMBOXBUF
pop di
pop cx
pop bx
push ds
mov ax, SEGGFX
mov ds, ax
MBox_LNextLn: push cx
mov cx, bx
rep movsb
add di, CSCRCOLUMN
sub di, bx
add si, CSCRCOLUMN
sub si, bx
pop cx
loop MBox_LNextLn
pop ds
clc
MBox_End: popa
ret
MessageBox ENDP
; ****************************************************************************
; Funktionen zur Bewegung des Cursors: C
; ****************************************************************************
MoveDown PROC
push ax
mov ax, yPos
cmp ax, BOTTOMLINE
je MoveDown_Scroll
inc yPos
clc
jmp MoveDown_End
MoveDown_Scroll:stc
MoveDown_End: pop ax
ret
MoveDown ENDP
MoveLeft PROC
push ax
mov ax, xPos
cmp ax, LEFTCOLUMN
je MoveLeft_Jump
dec xPos
clc
jmp MoveLeft_End
MoveLeft_Jump: mov ax, RIGHTCOLUMN
mov xPos, ax
call MoveUp
MoveLeft_End: pop ax
ret
MoveLeft ENDP
MoveRight PROC
push ax
mov ax, xPos
cmp ax, RIGHTCOLUMN
je MoveRight_Jump
inc xPos
clc
jmp MoveRight_End
MoveRight_Jump: mov ax, LEFTCOLUMN
mov xPos, ax
call MoveDown
MoveRight_End: pop ax
ret
MoveRight ENDP
MoveToBottom PROC
push ax
mov ax, BOTTOMLINE
mov yPos, ax
pop ax
ret
MoveToBottom ENDP
MoveToLeft PROC
push ax
mov ax, LEFTCOLUMN
mov xPos, ax
pop ax
ret
MoveToLeft ENDP
MoveToNextLine PROC
push ax
mov ax, LEFTCOLUMN
mov xPos, ax
call MoveDown
pop ax
ret
MoveToNextLine ENDP
MoveToRight PROC
push ax
mov ax, RIGHTCOLUMN
mov xPos, ax
pop ax
ret
MoveToRight ENDP
MoveToTop PROC
push ax
mov ax, TOPLINE
mov yPos, ax
pop ax
ret
MoveToTop ENDP
MoveUp PROC
push ax
mov ax, yPos
cmp ax, TOPLINE
je MoveUp_Scroll
dec yPos
clc
jmp MoveUp_End
MoveUp_Scroll: stc
MoveUp_End: pop ax
ret
MoveUp ENDP
; *****************************************************************************
; Versetzt das mit iObject angegebene Objekt zufällig
; *****************************************************************************
MoveObject PROC
pusha
; Adresse des Objekttypes bestimmen
;
mov ax, iItem
mov dx, CSCRCOLUMN * COBJLINE
mul dx
add ax, 0A0H
mov si, OFFSET aoffsItem
add si, iObject
add si, iObject
mov ds:[si], ax
; Adresse der Maske bestimmen
;
add si, OFFSET aoffsMask - OFFSET aoffsItem
mov ax, iItem
mov dx, CBOBJMASK / CITEM
mul dx
add ax, OFFSET aaabObjMask
mov ds:[si], ax
; Startadresse in Grafik bestimmen
;
add si, OFFSET aoffsObjNew - OFFSET aoffsMask
call GetRandom
mov dx, Random
mov ax, (CSCRCOLUMN - COBJCOLUMN) / CBITMAP
mul dx
mov bx, dx
call GetRandom
mov dx, CSCRLINE - COBJLINE
mov ax, Random
mul dx
mov ax, CSCRCOLUMN
mul dx
add ax, bx
mov ds:[si], ax
popa
ret
MoveObject ENDP
; *****************************************************************************
; Öffnen der Datei zum Abspielen
; *****************************************************************************
IFDEF _PLAY
OpenFile PROC
push ax
push dx
mov ax, offsText
shr ax, 4
mov dx, ds
add ax, dx
mov segText, ax
and offsText, 0000FH
pop dx
pop ax
clc
ret
OpenFile ENDP
ENDIF
; *****************************************************************************
; Öffnen der Textdatei zum lesen: C
; *****************************************************************************
IFDEF _READ
OpenFile PROC
push ax
push dx
mov ah, DOS_OPEN_FILE
xor al, al
mov dx, offsFileName
push ds
mov ds, segFileName
int DOS_FUNCTION
pop ds
mov skey, ax
pop dx
pop ax
ret
OpenFile ENDP
ENDIF
; *****************************************************************************
; Öffnen der Textdatei zum schreiben: C
; *****************************************************************************
IFDEF _WRITE
OpenFile PROC
pusha
mov ah, DOS_CREATE_FILE
xor cx, cx
mov dx, offsFileName
push ds
mov ds, segFileName
int DOS_FUNCTION
pop ds
mov skey, ax
popa
ret
OpenFile ENDP
ENDIF
; ****************************************************************************
; Bestimmt die Position eines Zeichens (> cx) in einem String (< di)
; ****************************************************************************
Pos PROC
push dx
push es
push ds
pop es
xor cx, cx
dec cx
push ax
push di
xor al, al
repne scasb
not cx
mov dx, cx
pop di
pop ax
repne scasb
or cx, cx
je Pos_Failure
sub dx, cx
mov cx, dx
dec cx
clc
jmp Pos_End
Pos_Failure: stc
Pos_End: pop es
pop dx
ret
Pos ENDP
; *****************************************************************************
; Gibt ein Zeichen auf dem Bildschirm aus
; *****************************************************************************
Print PROC
pusha
; Sequencer-Controller einstellen
;
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
inc dx
mov al, 080H
mov BitPlane, al
; Bildschirmadresse bestimmen: es:[di]
;
mov di, Offs
; Adresse der Zeichenmusters bestimmen: ds:[si]
;
mov si, Char
shl si, 3
add si, offsFont
; Anfangsadresse der Füllmusters bestimmen: ds:[bx]
;
mov bx, offsPattern
; Anfangsadresse der Füllfarben bestimmem: ds:[bp]
;
mov bp, offsPalette
mov cx, CCURLINE
Print_NextLn: push cx
lodsb
mov ah, al
mov cx, CCURCOLUMN
Print_NextCol: mov al, BitPlane
rol al, 1
cmp al, 010H
jne Print_NoReMap
mov al, 001H
inc di
Print_NoReMap: out dx, al
mov BitPlane, al
push dx
shl ah, 1
jnc Print_Back
; Pixel in der Vordergrundfarbe setzen
;
Print_Front: xor dh, dh
mov dl, ds:[bx]
add bp, dx
mov al, ds:[bp]
sub bp, dx
jmp Print_Pixel
; Pixel in der Hintergrundfarbe setzen
;
Print_Back: mov al, BackColor
Print_Pixel: mov es:[di], al
inc bx
pop dx
loop Print_NextCol
add di, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
pop cx
loop Print_NextLn
popa
ret
Print ENDP
; *****************************************************************************
; Setzt die Schreibposition auf die Cursorposition
; *****************************************************************************
ResetCursor PROC
push ax
mov ax, xPos
mov CursorNewX, ax
mov ax, yPos
mov CursorNewY, ax
pop ax
ret
ResetCursor ENDP
; *****************************************************************************
; Springt zum Anfang der Datei
; *****************************************************************************
IFDEF _WRITE
ResetFile PROC
pusha
; Dateizeiger an Anfang zurücksetzen
;
mov ah, DOS_MOVE_FILE_POINTER
xor al, al
mov bx, sKey
xor cx, cx
xor dx, dx
int DOS_FUNCTION
; Bildschirm löschen und Cursor in obere linke Ecke bewegen
;
call DoClear
call MoveToLeft
call MoveToTop
; Effekte auf Anfangswerte setzen
;
mov si, OFFSET aenFXDefault
mov di, OFFSET aenFX
mov cx, CFX
ResetFile_FX: mov al, ds:[si]
cmp al, ds:[di]
je ResetFile_FXNo
dec BYTE PTR ds:[di]
and BYTE PTR ds:[di], 3
ResetFile_FXNo: inc si
inc di
loop ResetFile_FX
; Einstellungen zurücksetzen
;
ResetFile_SpOn: mov iItem, 0
mov ynInsert, YES
mov BackColor, PABLACK
mov iCursor, 0
mov iPhase, 0
mov offsCursor, OFFSAAABCUR
mov offsFont, OFFSAAABFONTS
mov offsPalette, OFFSET AABCOLOR
mov offsPattern, OFFSET AAPATTERN
popa
ret
ResetFile ENDP
ENDIF
ResetInput PROC
mov Char, 0
mov Timer, 0
mov TimerLast, 0
mov Delay, 0
mov iFrame, 0
mov ynLock, OFF
mov ynSingle, NO
mov ynSkip, NO
mov cRepeat, 0
ret
ResetInput ENDP
; *****************************************************************************
; Arbeitet den Ablauf synchron zum Kathodenstrahl ab
; *****************************************************************************
Run PROC
push ax
IFNDEF _WRITE
call AccessFile
mov cRepeat, 0
jc Run_End
ENDIF
; Auf neuen Bildschirm warten
;
Run_Next: call ExpectPicture
call ExpectRetrace
; Bildschirme vertauschen
;
call SwitchFrame
; Zeichen auf zweitem Bildschirm wiederholen
;
cmp cRepeat, 0
jne Run_Key
; Zeichen nur vom ersten Bildschirm annehmen
;
cmp iFrame, 0
jne Run_NoKey
; Zeichen lesen und zwei Wiederholungen setzen
;
call GetKey
jc Run_NoKey
mov cRepeat, CFRAME
; Effekte während Zeichenausgabe abschalten
;
Run_Key: call TurnOffFX
call DoABC
cmp ynSkip, YES
je Run_Skip
; Uhr weiterstellen
;
mov ax, 1
call EnhanceTimer
Run_Skip: mov ynSkip, NO
call TurnOnFX
; Weitermachen, solange nicht am Ende
;
cmp ynQuit, YES
jne Run_Next
cmp cRepeat, 0
jne Run_Next
jmp Run_Exit
; Aktualisiert nur den Cusor und die Objekte
;
Run_NoKey: call TurnOffFX
; Uhr weiterstellen
;
mov ax, 1
call EnhanceTimer
call TurnOnFX
jmp Run_Next
Run_Exit: IFNDEF _WRITE
call AskEnd
clc
ENDIF
Run_End: pop ax
ret
Run ENDP
; *****************************************************************************
; Sichert die Bildattribute
; *****************************************************************************
SaveAttributes PROC
push es
push si
push di
mov di, OFFSET abAttribBuffer
mov si, OFFSET CursorX
push ds
pop es
movsw
movsw
mov si, OFFSET BackColor
movsb
mov si, OFFSET offsPalette
movsw
mov si, OFFSET offsPattern
movsw
mov si, OFFSET offsFont
movsw
pop di
pop si
pop es
ret
SaveAttributes ENDP
SwitchFrame PROC
push ax
push si
; Cursor-Position sichern
;
mov si, iFrame
inc si
shl si, 2
add si, OFFSET xPos
mov ax, xPos
mov ds:[si], ax
mov ax, yPos
mov ds:[si+2], ax
mov ax, iFrame
xor ax, 1
mov iFrame, ax
mov ax, offsFrame
xor ax, CSCRCOLUMN / CBITMAP
mov offsFrame, ax
shr ax, 4
or ax, SEGGFX
mov es, ax
; Cursor-Position restaurieren
;
mov si, iFrame
inc si
shl si, 2
add si, OFFSET xPos
mov ax, ds:[si]
mov xPos, ax
mov ax, ds:[si+2]
mov yPos, ax
pop si
pop ax
ret
SwitchFrame ENDP
SwitchCursor PROC
dec enCursor
and enCursor, 3
ret
SwitchCursor ENDP
SwitchSprites PROC
dec enObjects
and enObjects, 3
ret
SwitchSprites ENDP
SwitchStars PROC
dec enStars
and enStars, 3
ret
SwitchStars ENDP
; ****************************************************************************
; Stellt den Hintergrund des Cursors wieder her
; ****************************************************************************
TurnOffCursor PROC
pusha
call GetCurOffset
mov di, offs
mov si, OFFSET OFFSAABCURBUF
mov ax, iFrame
add ax, ax
add si, ax
push ds
mov ax, SEGGFX
mov ds, ax
mov cx, CCURLINE
TOfCur_NextLn: push cx
mov cx, CCURCOLUMN / CBITMAP
rep movsb
add si, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
add di, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
pop cx
loop TOfCur_NextLn
pop ds
popa
ret
TurnOffCursor ENDP
; ****************************************************************************
; Schaltet den Cursor ein
; ****************************************************************************
TurnOnCursor PROC
pusha
call GetCurOffset
; Sicherung des Hintergrundes
;
mov si, offs
mov di, OFFSET OFFSAABCURBUF
mov ax, iFrame
add ax, ax
add di, ax
push ds
push es
push es
pop ds
mov ax, SEGGFX
mov es, ax
mov cx, CCURLINE
TOnCur_SNextLn: push cx
mov cx, CCURCOLUMN / CBITMAP
rep movsb
add si, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
add di, CSCRCOLUMN - (CCURCOLUMN / CBITMAP)
pop cx
loop TOnCur_SNextLn
pop es
pop ds
; Zeichnet den Cursor neu
;
mov si, iPhase
shr si, 1
and si, 0FFFEH
add si, offsCursor
mov di, offs
push ds
mov ax, SEGGFX
mov ds, ax
mov cx, CCURLINE
TOnCur_CNextLn: push cx
mov cx, CCURCOLUMN / CBITMAP
rep movsb
add di, CSCRCOLUMN - CCURCOLUMN / CBITMAP
add si, CSCRCOLUMN - CCURCOLUMN / CBITMAP
pop cx
loop TOnCur_CNextLn
pop ds
popa
ret
TurnOnCursor ENDP
TurnOffFX PROC
pusha
; Kontrolle, ob Effekte schon aus sind
;
cmp ynFXOn, OFF
je TurnOffFX_End
mov ynFXOn, OFF
; Alle gewählten Objekte einschalten
;
mov si, OFFSET aenFX + (CFX - 1)
mov di, OFFSET ATURNOFFPROC + (CFX - 1) * 2
mov cx, CFX
TurnOffFX_Next: mov al, ds:[si]
inc al
and al, 3
cmp al, ENON
jl TurnOffFX_Not
mov bx, ds:[di]
call bx
TurnOffFX_Not: dec si
sub di, 2
loop TurnOffFX_Next
TurnOffFX_End: popa
ret
TurnOffFX ENDP
TurnOnFX PROC
pusha
; Kontrolle, ob Effekte schon an sind
;
cmp ynFXOn, ON
je TurnOnFX_End
mov ynFXOn, ON
; Alle gewählten Objekte einschalten
;
mov si, OFFSET aenFX
mov di, OFFSET ATURNONPROC
mov cx, CFX
TurnOnFX_Next: cmp BYTE PTR ds:[si], ENON
jl TurnOnFX_Not
mov bx, ds:[di]
call bx
TurnOnFX_Not: inc si
add di, 2
loop TurnOnFX_Next
TurnOnFX_End: popa
ret
TurnOnFX ENDP
; *****************************************************************************
; Löschen aller Objekte
; *****************************************************************************
TurnOffObjects PROC
pusha
xor cx, cx
; Anfangsadresse der Hintergrund-Puffers bestimmen: es:si
;
TOfObj_Next: mov si, cx
shl si, 2
add si, OFFSAAABOBJBUF
mov ax, iFrame
or ax, ax
je TOfObj_F1
add si, CSCRCOLUMN * COBJLINE
; Anfangsadresse des Hintergrundes bestimmen: es:di
;
TOfObj_F1: mov di, iFrame
shl di, 4
add di, OFFSET aoffsObj
add di, cx
add di, cx
mov di, ds:[di]
; Hintergrund wiederherstellen
;
push cx
push ds
mov ax, SEGGFX
mov ds, ax
mov cx, COBJLINE
TOfObj_SNextLn: push cx
mov cx, COBJCOLUMN / CBITMAP
rep movsb
add si, CSCRCOLUMN - COBJCOLUMN / CBITMAP
add di, CSCRCOLUMN - COBJCOLUMN / CBITMAP
pop cx
loop TOfObj_SNextLn
pop ds
pop cx
inc cx
cmp cx, COBJECT
jne TOfObj_Next
popa
ret
TurnOffObjects ENDP
; *****************************************************************************
; Neuzeichnen der Objekte
; *****************************************************************************
TurnOnObjects PROC
pusha
mov cx, COBJECT - 1
; Kontrolle, ob das Objekt bewegt werden muß
;
TOnObj_Next: xor dh, dh
mov si, OFFSET abObjTimer
add si, cx
mov dl, ds:[si]
or dl, dl
jns TOnObj_NoMove
xor dl, dl
mov iObject, cx
call MoveObject
; Anfangsadresse des Hintergrundes bestimmen: es:si
;
TOnObj_NoMove: mov ds:[si], dl
shr dl, 3
mov si, OFFSET aoffsObjNew
add si, cx
add si, cx
mov ax, ds:[si]
mov di, iFrame
shl di, 4
add di, OFFSET aoffsObj
add di, cx
add di, cx
mov ds:[di], ax
mov si, ax
; Anfangsadresse der Hintergrund-Puffers bestimmen: es:di
;
mov di, cx
shl di, 2
add di, OFFSAAABOBJBUF
mov ax, iFrame
or ax, ax
je TOnObj_F1
add di, CSCRCOLUMN * COBJLINE
; Hintergrund sichern
;
TOnObj_F1: push cx
push es
push ds
push es
pop ds
mov ax, SEGGFX
mov es, ax
push si
mov cx, COBJLINE
TOnObj_SNextLn: push cx
mov cx, COBJCOLUMN / CBITMAP
rep movsb
add si, CSCRCOLUMN - COBJCOLUMN / CBITMAP
add di, CSCRCOLUMN - COBJCOLUMN / CBITMAP
pop cx
loop TOnObj_SNextLn
; Hintergrundadresse bestimmen: es:[di]
;
pop di
pop ds
pop es
; Anfangsadresse des Objekts bestimmen: es:[si]
;
pop cx
push cx
mov si, OFFSET AOBJECTSEQ
add si, dx
mov al, ds:[si]
xor ah, ah
mov dx, ax
shl ax, 2
mov si, OFFSET aoffsItem
add si, cx
add si, cx
mov si, ds:[si]
add si, ax
; Adresse der Maske bestimmen: ds:bx
;
mov bx, OFFSET aoffsMask
add bx, cx
add bx, cx
mov bx, ds:[bx]
mov ax, COBJLINE * COBJCOLUMN / CBITMAP
mul dx
add bx, ax
; Sequencer-Controller einstellen
;
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
inc dx
; Objekt auf Hintergrund kopieren
;
mov bp, ds
mov ax, SEGGFX
mov ds, ax
mov cx, COBJLINE
TOnObj_CNextLn: push cx
mov cx, COBJCOLUMN / CBITMAP
TOnObj_CNextCl: push ds
mov ds, bp
mov al, ds:[bx]
pop ds
out dx, al
mov al, ds:[si]
mov es:[di], al
inc bx
inc si
inc di
loop TOnObj_CNextCl
add si, CSCRCOLUMN - COBJCOLUMN / CBITMAP
add di, CSCRCOLUMN - COBJCOLUMN / CBITMAP
pop cx
loop TOnObj_CNextLn
mov ds, bp
mov al, 00FH
out dx, al
; Nächstes Objekt
;
pop cx
dec cx
js TOnObj_End
jmp TOnObj_Next
TOnObj_End: popa
ret
TurnOnObjects ENDP
TurnOffStars PROC
pusha
; Sequencer-Controller einstellen
;
call DoneBlit
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
mov dx, PRGRAPHICS
mov al, 004H
out dx, al
mov cx, CSTAR
xor di, di
cmp iFrame, 0
jne TOffStr_Page2
mov si, OFFSET awStarX
jmp TOffStr_Next
TOffStr_Page2: mov si, OFFSET awStarX + 2 * CSTAR
TOffStr_Next: push cx
push di
mov bx, ds:[si]
mov cl, bl
and cl, 3
mov al, 1
shl al, cl
mov dx, PRSEQUENCER + 1
out dx, al
mov al, cl
mov dx, PRGRAPHICS + 1
out dx, al
shr bx, 2
add di, bx
mov al, es:[di]
cmp al, CSTARCOLOR
ja TOffStr_No
mov BYTE PTR es:[di], 0
TOffStr_No: add si, 2
pop di
add di, CSCRCOLUMN
pop cx
loop TOffStr_Next
call InitBlit
popa
ret
TurnOffStars ENDP
TurnOnStars PROC
pusha
; Sequencer-Controller einstellen
;
call DoneBlit
mov dx, PRSEQUENCER
mov al, 002H
out dx, al
mov dx, PRGRAPHICS
mov al, 004H
out dx, al
mov cx, CSTAR
xor di, di
cmp iFrame, 0
jne TOnStr_Page2
mov si, OFFSET awStarX
jmp TOnStr_Next
TOnStr_Page2: mov si, OFFSET awStarX + 2 * CSTAR
TOnStr_Next: push cx
push di
mov ah, cl
and ah, 3
inc ah
mov bx, ds:[si]
mov cl, bl
and cl, 3
mov al, 1
shl al, cl
mov dx, PRSEQUENCER + 1
out dx, al
mov al, cl
mov dx, PRGRAPHICS + 1
out dx, al
shr bx, 2
add di, bx
mov al, es:[di]
cmp al, CSTARCOLOR
ja TOnStr_Above
mov es:[di], ah
TOnStr_Above: add si, 2
pop di
add di, CSCRCOLUMN
pop cx
loop TOnStr_Next
call InitBlit
popa
ret
TurnOnStars ENDP
; *****************************************************************************
; Wandelt einen Buchstaben in einen Großbuchstaben um
; *****************************************************************************
UpCase PROC
cmp Char, 'a'
jnae UpCase_End
cmp Char, 'z'
ja UpCase_End
add Char, 'A' - 'a'
UpCase_End: ret
UpCase ENDP
VoidProc PROC
ret
VoidProc ENDP
; *****************************************************************************
; Wartet auf einen Tastendruck
; *****************************************************************************
WaitKey PROC
; Auf neuen Bildschirm warten
;
WaitKey_More: call ExpectPicture
call ExpectRetrace
; Uhr weiterstellen
;
cmp ynLock, YES
je WaitKey_Locked
inc Timer
WaitKey_Locked: call GetKey
jc WaitKey_More
ret
WaitKey ENDP
; ****************************************************************************
; Schaltet die Rahmenfarbe auf Weiß
; ****************************************************************************
IFDEF _TEST
WhiteBorder PROC
push ax
push dx
mov dx, 003C0H
mov al, 031H
out dx, al
mov al, 03FH
out dx, al
pop dx
pop ax
ret
WhiteBorder ENDP
ENDIF
; ****************************************************************************
; Gibt eine Zeichenkette aus
; ****************************************************************************
Write PROC
pusha
call SaveAttributes
mov si, MBox_Text
mov dx, MBox_Left
inc dx
mov CursorX, dx
mov dx, MBox_Top
inc dx
mov CursorY, dx
Write_Next: xor ah, ah
lodsb
cmp al, CHBACK
je Write_Back
cmp al, CHTEXT
je Write_Front
cmp al, CHPATTERN
je Write_Pattern
cmp al, CHFONT
je Write_Font
mov Char, ax
call GetCurOffset
call DoneBlit
call Print
call InitBlit
inc CursorX
mov ax, CursorX
cmp ax, MBox_Right
jne Write_Next
inc CursorY
mov ax, CursorY
cmp ax, MBox_Bottom
je Write_End
mov ax, MBox_Left
inc ax
mov CursorX, ax
jmp Write_Next
Write_Back: lodsb
mov BackColor, al
jmp Write_Next
Write_Font: lodsb
shl ax, 11
add ax, OFFSAAABFONTS
mov offsFont, ax
jmp Write_Next
Write_Front: lodsb
shl ax, 4
add ax, OFFSET AABCOLOR
mov offsPalette, ax
jmp Write_Next
Write_Pattern: lodsb
shl ax, 6
add ax, OFFSET AAPATTERN
mov offsPattern, ax
jmp Write_Next
Write_End: call LoadAttributes
popa
ret
Write ENDP
Code ENDS
END Main