mbr_tsr
Joined: 03 Apr 2011
Posts: 12092
|
There are more commands in this thing now, like goto, input, and compare. I ported it from an OS Kernel/MS-DOS/and Windows version to Linux.
;EMU2.ASM
;Make your own compiler
;This is a simple example of writing your own language
;It is easy to add commands
;You can run scripts placed in the Script: label
;Has a very nice command parser
;Variables are @0 to @9 set by using "set #" from 0 to 9
;Scripts can have more than one command in a line using |
;Every line of a script is terminated with a CRLF
;All scripts must end with the 'stop' command
;It would be easy to make your scripts into .com programs
;Port your scripts to Windows, DOS, and Linux, or Raw
;By Atomic_Bios (Feb. 2011)
Org 100h
format ELF executable
entry start
segment readable writable
start:
mov EDI, VarBuff
mov ECX, 1000 * 10
mov al, 0
ClearVars:
stosb
loop ClearVars
mov esi, Intro
call TinyPrint
Main:
mov edi, String
mov ecx, 7000
mov al, 0
ClearStr:
stosb
loop ClearStr
cmp [Running], 1
jne NotRunning
mov ESI, Script
mov eax, [CurrentLine]
call PointP
GotOneAlready:
cmp byte [ESI], 10
jne NoIncLF
inc ESI
NoIncLF:
mov EDI, String
call CopyString
inc [CurrentLine]
jmp SkipInput
NotRunning:
;We will skip the input prompt if running script
mov esi, InputPrompt
call TinyPrint
mov ESI, String
call TinyInput
SkipInput:
mov EDI, Buffer1
mov ECX, BuffSize * 4
mov al, 0
ClearBuffs:
stosb
loop ClearBuffs
call ParseCommand
cmp [Debug], 0
je NotDebugging1
call ShowVars
mov esi, CrLf
call TinyPrint
NotDebugging1:
mov ESI, Buffer1
mov EDI, Cmd10
call Compare
cmp eax, 1
je InputCmd
;This will put variables into command buffers
;sends typed @0 to @9 buffer into parse buffer
mov ECX, 10
mov EBP, 0
mov EBX, 0
ScannBufferVars:
push ECX
mov ESI, VariableList
mov EAX, EBP
call PointP
push EBP
mov ECX, EAX
mov EBP, VarBuff
cmp EAX, 0
je ItsNulZ
IncScans:
add EBP, 1000
loop IncScans
ItsNulZ:
mov ECX, 4
mov EDI, Buffer1
TheBuffers:
push ECX
call Compare
cmp eax, 0
je NotMatch
mov ESI, EBP
call CopyString
NotMatch:
add EDI, BuffSize
pop ECX
loop TheBuffers
pop EBP
inc EBP
pop ECX
loop ScannBufferVars
InputCmd:
;Here we will test what command was entered and react
mov ESI, Buffer1
mov EDI, Cmd00
call Compare
cmp eax, 0
je NotCmd00
ForceQuit:
mov eax,1 ;linux quit
xor ebx,ebx
int 0x80
jmp CommandDone
NotCmd00:
mov ESI, Buffer1
mov EDI, Cmd01
call Compare
cmp eax, 0
je NotCmd01
mov ESI, Buffer2
call TinyPrint
mov esi, CrLf
call TinyPrint
jmp CommandDone
NotCmd01:
mov ESI, Buffer1
mov EDI, Cmd02
call Compare
cmp eax, 0
je NotCmd02
mov ESI, Help
call TinyPrint
jmp CommandDone
NotCmd02:
mov ESI, Buffer1
mov EDI, Cmd03
call Compare
cmp eax, 0
je NotCmd03
mov ESI, Beep
call TinyPrint
jmp CommandDone
NotCmd03:
mov ESI, Buffer1
mov EDI, Cmd04
call Compare
cmp eax, 0
je NotCmd04
mov [Running], 1
mov ESI, Script
mov EDI, Script
mov ECX, StrSize
MakeFormat:
lodsb
cmp al, '|'
je MultiCmd
cmp al, 13
jne Not13
MultiCmd:
mov al,0
Not13:
stosb
loop MakeFormat
jmp CommandDone
NotCmd04:
mov ESI, Buffer1
mov EDI, Cmd05
call Compare
cmp eax, 0
je NotCmd05
mov [Running], 0
mov [CurrentLine], 0
mov [GotoLine], 0
jmp Main
NotCmd05:
mov ESI, Buffer1
mov EDI, Cmd06
call Compare
cmp eax, 0
je NotCmd06
cmp byte [Debug], 0
je TurnOn
cmp byte [Debug], 1
je TurnOff
mov [Debug], 1
jmp DoneDebugSetup
TurnOn:
mov [Debug], 1
jmp DoneDebugSetup
TurnOff:
mov [Debug], 0
DoneDebugSetup:
jmp CommandDone
NotCmd06:
mov ESI, Buffer1
mov EDI, Cmd07
call Compare
cmp eax, 0
je NotCmd07
mov esi, Buffer2
call ScanHex
mov ECX, EAX
mov ESI, Buffer3
mov EDI, VarBuff
cmp ECX, 0
jle ZeroBaby
cmp ECX, 9
ja OUA
IncScan:
add EDI, 1000
loop IncScan
ZeroBaby:
call CopyString
OUA:
jmp CommandDone
NotCmd07:
mov ESI, Buffer1
mov EDI, Cmd08
call Compare
cmp eax, 0
je NotCmd08
DirectGoto:
cmp [Running], 0
je SkipGoto
mov ESI, Buffer2
mov EDI, Buffer2
CutLabM:
lodsb
cmp al, ' '
je CutLabM
cmp al, 0
je DoneLabM
stosb
jmp CutLabM
DoneLabM:
mov al, 0
stosb
mov [GotoLine], 0
mov ECX, 64000
ScanGotoLines:
mov ESI, Script
mov EAX, [GotoLine]
mov EDI, TrimBuff
call PointP
StartTrim:
lodsb
cmp al, 0
je DoneScan
cmp al, ' '
jne NotSpace1
jmp SkipStore
NotSpace1:
stosb
SkipStore:
jmp StartTrim
DoneScan:
mov al, 0
stosb
mov ESI, TrimBuff
cmp byte [ESI], 10
jne NoIncLFG
inc ESI
NoIncLFG:
mov EDI, Buffer2
call Compare
cmp eax, 1
je GotGotoLine
inc [GotoLine]
loop ScanGotoLines
jmp ErrOut
GotGotoLine:
mov EAX, [GotoLine]
mov [CurrentLine], EAX
jmp Main
ErrOut:
SkipGoto:
jmp CommandDone
NotCmd08:
mov ESI, Buffer1
mov EDI, Cmd09
call Compare
cmp eax, 0
je NotCmd09
mov ESI, Buffer2
mov EDI, Buffer3
call Compare
cmp eax, 0
je NotSame
mov ESI, Buffer4
jmp GotOneAlready
NotSame:
jmp CommandDone
NotCmd09:
mov ESI, Buffer1
mov EDI, Cmd10
call Compare
cmp eax, 0
je NotCmd10
mov EDI, VarBuff
mov ECX, 10
mov EBP, 0
ScanInpVars:
push ECX
mov ESI, Var0
mov EAX, EBP
call PointP
push EDI
mov EDI, Buffer2
call Compare
pop EDI
cmp eax, 0
je NotInpVar1
pop ECX
mov ESI, EDI
mov ecx, 1000
mov al, 0
ClearStrI:
stosb
loop ClearStrI
call TinyInput
jmp GotInput
NotInpVar1:
add EDI, 1000
inc EBP
pop ECX
loop ScanInpVars
GotInput:
jmp CommandDone
NotCmd10:
mov ESI, Buffer1
mov EDI, Cmd11
call Compare
cmp eax, 0
je NotCmd11
;Add your command contents here
jmp CommandDone
NotCmd11:
mov ESI, Buffer1
mov EDI, Cmd12
call Compare
cmp eax, 0
je NotCmd12
;Add your command contents here
jmp CommandDone
NotCmd12:
mov ESI, Buffer1
mov EDI, Cmd13
call Compare
cmp eax, 0
je NotCmd13
;Add your command contents here
jmp CommandDone
NotCmd13:
mov ESI, Buffer1
mov EDI, Cmd14
call Compare
cmp eax, 0
je NotCmd14
;Add your command contents here
jmp CommandDone
NotCmd14:
mov ESI, Buffer1
mov EDI, Cmd15
call Compare
cmp eax, 0
je NotCmd15
;Add your command contents here
jmp CommandDone
NotCmd15:
cmp byte [Debug],0
je NotDebuggingGarb
mov esi, Error
call TinyPrint
mov esi, CrLf
call TinyPrint
call ShowVars
NotDebuggingGarb:
jmp AllOver
CommandDone:
cmp byte [Debug],0 ;Show okay message if debugging
je NotDebugging2
mov esi, Okay
call TinyPrint
NotDebugging2:
AllOver:
jmp Main
ParseCommand:
mov edi, Buffer1
mov ecx, BuffSize
mov edx, 0
mov eax, 4
mul ecx
mov ecx, eax
mov al, 0
ClearTheMem:
stosb
loop ClearTheMem
mov esi, String
GoParse:
mov ecx, BuffSize
ltrim:
mov al, byte [esi]
cmp al, ' '
jne DoneIt
inc esi
loop ltrim
DoneIt:
mov byte [incy], 0
mov byte [qcount], 0
mov EBX, 0
mov EDX, 0
mov ECX, 0
mov AL, 1
Parses:
mov AL, byte [ESI+EBX]
inc EBX
cmp al, 13
jne Cant13
mov al, 0
Cant13:
cmp al, 10
jne Cant10
mov al, 0
Cant10:
cmp AL, ';'
je EndParses
cmp AL, ' '
jne NotSpace
CommaAsSpace:
cmp byte [qcount], 1
je OkayW
mov ECX, 128
FixMultiSpaceInc:
mov AL, byte [ESI+EBX]
cmp al, ','
je CommaSameAsSpace
cmp al, ' '
jne CeaseSpc
CommaSameAsSpace:
inc EBX
loop FixMultiSpaceInc
CeaseSpc:
inc byte [incy]
mov EDX, 0
jmp Trim
NotSpace:
cmp AL, ','
je CommaAsSpace
cmp AL, 34
jne NotQuote
cmp byte [qcount], 0
je SetTo1
mov byte [qcount], 0
jmp Trim
SetTo1:
mov byte [qcount], 1
jmp Trim
NotQuote:
OkayW:
cmp byte [incy], 0
je Zero
cmp byte [incy], 1
je One
cmp byte [incy], 2
je Two
cmp byte [incy], 3
je Three
jmp EndParses
Zero:
mov EDI, Buffer1
add EDI, EDX
mov byte [EDI], AL
inc EDX
jmp Trim
One:
mov EDI, Buffer2
add EDI, EDX
mov byte [EDI], AL
inc EDX
jmp Trim
Two:
mov EDI, Buffer3
add EDI, EDX
mov byte [EDI], AL
inc EDX
jmp Trim
Three:
mov EDI, Buffer4
add EDI, EDX
mov byte [EDI], AL
inc EDX
jmp Trim
Trim:
cmp AL, 0
je EndParses
jmp Parses
EndParses:
ret
;Read input from keyboard into ESI
TinyInput:
pushad
mov eax, 3 ; __NR_read (/linux/include/asm/unistd.h)
mov ebx, 0 ; iirc handle 0 is stdin
mov ecx, ESI
mov edx, 7000
int 80h
popad
ret
;print ESI to the screen
TinyPrint:
pushad
mov eax,4
mov ebx,1
call StrLen
mov EDX, ECX
mov ecx,ESI
int 0x80
popad
ret
StrLen:
push esi
push eax
mov ecx, 0
StrLenC:
lodsb
cmp al, 0
je DoneGotLen
cmp al, '$'
je DoneGotLen
inc ecx
jmp StrLenC
DoneGotLen:
pop eax
pop esi
ret
ShowVars:
mov esi, CrLf
call TinyPrint
mov esi, Bar
call TinyPrint
mov esi, Data0
call TinyPrint
mov esi, String
call TinyPrint
mov esi, CrLf
call TinyPrint
mov esi, Data1
call TinyPrint
mov esi, Buffer1
call TinyPrint
mov esi, CrLf
call TinyPrint
mov esi, Data2
call TinyPrint
mov esi, Buffer2
call TinyPrint
mov esi, CrLf
call TinyPrint
mov esi, Data3
call TinyPrint
mov esi, Buffer3
call TinyPrint
mov esi, CrLf
call TinyPrint
mov esi, Data4
call TinyPrint
mov esi, Buffer4
call TinyPrint
mov esi, CrLf
call TinyPrint
mov esi, Bar
call TinyPrint
mov EDX, 0
mov ECX, 10
Debuggy:
mov ESI, VariableList
mov EAX, EDX
push EDX
call PointP
call TinyPrint
mov ESI, VarBuff
mov EAX, EDX
mov EBX, 1000
mul EBX
add ESI, EAX
call TinyPrint
mov esi, CrLf
call TinyPrint
pop EDX
inc EDX
loop Debuggy
ret
;compare esi with edi if they are the same return eax as 1
;if they are not the same return eax as 0
Compare:
push edi
push esi
mov eax, 0
c_loop2:
lodsb
cmp byte [edi], al
jne c_nope2
cmp al, 00
je c_yup2
cmp al, 0x0a
je c_yup2
cmp al, 0x0d
je c_yup2
cmp al, '$'
je c_yup2
inc edi
jmp c_loop2
c_yup2:
mov eax, 01
jmp GotCmpVal
c_nope2:
mov eax, 00
jmp GotCmpVal
GotCmpVal:
pop esi
pop edi
ret
;call with ESI array and al element#
;points to a specific string withing array of NUL terminated strings
PointP:
push EAX
push ECX
push EDX
mov DL, AL
mov ECX, 64000
cmp DL, 0
je cAllOverPc
cCounterLoopc:
cmp byte [ESI], 0
jne cNotUpCountc
inc ESI
dec DL
cmp DL, 0
je cAllOverPc
cNotUpCountc:
inc ESI
loop cCounterLoopc
cAllOverPc:
pop EDX
pop ECX
pop EAX
ret
;copy string in ESI to EDI
CopyString:
push ESI
push EDI
CpyMem1:
mov AL, byte [ESI]
cmp AL, 0
je CopyOver
cmp AL, 0x0a
je CopyOver
cmp AL, 0x0d
je CopyOver
mov byte [EDI], AL
inc ESI
inc EDI
jmp CpyMem1
CopyOver:
mov byte [EDI], 0
pop EDI
pop ESI
ret
;convert hex in ds:si into ascii into AX or AL
ScanHex:
push esi
push ecx
push edx
mov cl,4
xor edx,edx
scn:
lodsb
cmp al,'0'
jb endr
cmp al,'9'
jna decdgt
or al,0x20
cmp al,'a'
jb endr
cmp al,'z'
ja endr
sub al,'a'-'9'-1
decdgt:
sub al,'0'
shl dx,cl
or dl,al
jmp scn
endr:
xchg edx, eax
dec esi
pop edx
pop ecx
pop esi
ret
CrLf db 0x0d,0x0a,0
incy db 0 ;keeps trek of parse
qcount db 0 ;keeps treq of quotes
Running db 0 ;0=user entry 1=running script
CurrentLine dd 0 ;line number of running program
GotoLine dd 0
Debug db 0
InputPrompt db 0x0d,0x0a,"?",0
Bar db "=========================================================",0x0d,0x0a,0
Data0 db "Command =",0
Data1 db "Paramiter1 =",0
Data2 db "Paramiter2 =",0
Data3 db "Paramiter3 =",0
Data4 db "Paramiter4 =",0
Intro db "ZOS32",0x0d,0x0a,0
Help db "Commands",0x0d,0x0a
db "exit = exit program and return to OS",0x0d,0x0a
db "print text = display a message on the screen",0x0d,0x0a
db "help = show this help screen info on commands",0x0d,0x0a
db "beep = send a beeping noise to the PC speaker",0x0d,0x0a
db "run = start running the built-in program script",0x0d,0x0a
db "stop = used by scripts to stop running themself",0x0d,0x0a
db "debug = toggle show extra info during commands",0x0d,0x0a
db "set # text = set variable from 0 to 9 to text",0x0d,0x0a
db "goto label: = goto any label: within your script",0x0d,0x0a
db "compare txt1 txt2 code = run code if txt1 and txt2 are equal",0x0d,0x0a
db "input @var = read keyboard input into @0 to @9",0x0d,0x0a
db "note that variable names are from @0 to @9",0x0d,0x0a
db 0
Beep db 7,0
CommandList:
Cmd00 db "exit",0
Cmd01 db "print",0
Cmd02 db "help",0
Cmd03 db "beep",0
Cmd04 db "run",0
Cmd05 db "stop",0
Cmd06 db "debug",0
Cmd07 db "set",0
Cmd08 db "goto",0
Cmd09 db "compare",0
Cmd10 db "input",0
Cmd11 db "empty",0
Cmd12 db "empty",0
Cmd13 db "empty",0
Cmd14 db "empty",0
Cmd15 db "empty",0
VariableList:
Var0 db "@0",0
Var1 db "@1",0
Var2 db "@2",0
Var3 db "@3",0
Var4 db "@4",0
Var5 db "@5",0
Var6 db "@6",0
Var7 db "@7",0
Var8 db "@8",0
Var9 db "@9",0
Error db "Error = Unknown command",0x0d,0x0a,0
Okay db "OKAY",0x0d,0x0a,0
Script:
db 'MainLabel:',0x0d,0x0a
db 'print "beeping three times"',0x0d,0x0a
db 'beep | beep | beep | print Done!',0x0d,0x0a
db 'InputLabel:',0x0d,0x0a
db 'print "Commands: exit, restart, help"',0x0d,0x0a
db 'input @1',0x0d,0x0a
db 'print "You Typed:" | print @1',0x0d,0x0a
db 'compare @1 restart "goto MainLabel:"',0x0d,0x0a
db 'compare @1 exit "goto ExitLabel:"',0x0d,0x0a
db 'compare @1 help "goto HelpLabel:"',0x0d,0x0a
db 'print "Unknown Command"',0x0d,0x0a
db 'goto InputLabel:',0x0d,0x0a
db 'ExitLabel:',0x0d,0x0a
db 'print Goodbye...',0x0d,0x0a
db 'stop',0x0d,0x0a
db 'HelpLabel:',0x0d,0x0a
db 'print "exit=return to OS',0x0d,0x0a
db 'print "restart=restart demo',0x0d,0x0a
db 'print "help=show command summary',0x0d,0x0a
db 'goto InputLabel:',0x0d,0x0a
ScriptSizeLimit rb 12000 ;Give some room for scripts
String rb 7000 ;the main command goes here
StrSize = $ - String
Buffer1 rb 1000 ;the paramiters go here
BuffSize = $ - Buffer1
Buffer2 rb 1000
Buffer3 rb 1000
Buffer4 rb 1000
VarBuff rb 1000 * 10
TrimBuff rb 88
db 0
|