Tavukoodia ja virtuaalikone(hko)

Jaa meneillään olevat projektisi tai valmiit pelit muun yhteisön kanssa täällä.
Post Reply
User avatar
naputtelija
Devoted Member
Posts: 718
Joined: Wed Nov 03, 2010 8:56 pm
Location: Joku piste pohjoisessa.

Tavukoodia ja virtuaalikone(hko)

Post by naputtelija » Thu Aug 02, 2012 7:46 pm

Tällainen. Suorittaa alussa määritellyn Konekieliohjelman, esitettynä alussa (rivit 23,33) assembly-koodina (pokebyteillä) voitte testata itsekin ja muuttaa konekieliohjelmaa, se suorittaa sen. Muistakaa muuttaa myös debug tekstiä riveillä 103-105, että saatte ohjelmanne tulokset esille.

Tässä on siis muutamia rekisterejä, mm. Akkumulaattori, ohjelmalaskuri, carry rekisteri, overflow (vain akkumulaattori ja ohjelmalaskuri ovat käytössä)

Assembly-komennot A on akkumulaattori, adr on muistiosoite joka määritellään komennon jälkeen. PC on ohjelmalaskuri. (Suoritettavan komennon muistiosoite)

Code: Select all

BRK...Keskeyttää::::::0x00=0
ORA...A=A or adr::::::0x01=1
ANA...A=A and adr:::::0x02=2
EOR...A=A xor adr:::::0x03=3
ADD...A=A+adr:::::::::0x04=4
SUB...A=A-adr:::::::::0x05=5
INC...A=A+1:::::::::::0x06=6
DEC...A=A-1:::::::::::0x07=7
LDA...A=adr:::::::::::0x08=8
STA...adr=A:::::::::::0x09=9
TAP...PC=A::::::::::::0x0A=10
TPA...A=PC::::::::::::0x0B=11
NOP...Ei mitään:::::::0xFF=255 (voi käyttää waittina :))

Code: Select all


mem=MakeMEMBlock(1024)
a=MakeMEMBlock(1)
pc=MakeMEMBlock(2)
o=MakeMEMBlock(1)
c=MakeMEMBlock(1)
s=MakeMEMBlock(1)
//Nämä ovat vain numeroarvojen muistamista varten koska niitä ei voi käyttää casessa
Const BRK  = 0
Const ORA  = 1
Const ANA  = 2
Const EOR  = 3
Const ADD  = 4
Const SUB  = 5
Const INC  = 6
Const DEC  = 7
Const LDA  = 8
Const STA  = 9
Const TAP  = 10
Const TPA  = 11
Const LDA2 = 12
Const NOP = 255
PokeByte mem,10,LDA
PokeByte mem,11,5
PokeByte mem,12,STA
PokeByte mem,13,50
PokeByte mem,14,INC
PokeByte mem,15,STA
PokeByte mem,16,51
PokeByte mem,17,INC
PokeByte mem,18,STA
PokeByte mem,19,52
PokeByte mem,20,BRK
PokeByte pc,0,9
isrunning=True
starttime=Timer()
cyclecount=0
cycle:
    PokeShort pc,0,PeekShort(pc,0)+1
    
    PokeByte mem,1023,PeekByte(mem,PeekByte(pc,0))
    Print "Executing "+PeekByte(mem,1023)
    Select PeekByte(mem,1023) 'Tee hommat
        Case 0
            isrunning=False
        Case 1
            PokeByte mem,0,1
        Case 2
            PokeByte mem,0,2
        Case 3
            PokeByte mem,0,3
        Case 4
            PokeByte mem,0,4
        Case 5
            PokeByte mem,0,5
        Case 6
            PokeByte a,0,PeekByte(a,0)+1 : Goto endi
        Case 7
            PokeByte a,0,PeekByte(a,0)-1 : Goto endi
        Case 8
            PokeByte mem,0,8
        Case 9
            PokeByte mem,0,9
        Case 10
            PokeByte pc,0,PeekByte(a,0) : Goto endi
        Case 11
            PokeByte a,0,PeekByte(pc,0) : Goto endi
        Case 12
            PokeByte mem,0,12
        Case 255
            Goto endi
    EndSelect
    
    PokeShort pc,0,PeekShort(pc,0)+1
    PokeByte mem,1023,PeekByte(mem,PeekByte(pc,0)) 'Lisää laskuria ja tallenna arvo
    Select PeekByte(mem,0)
        Case 1
            PokeByte a,0,BinOr(PeekByte(a,0),PeekByte(mem,1023))
        Case 2
            PokeByte a,0,BinAnd(PeekByte(a,0),PeekByte(mem,1023))
        Case 3
            PokeByte a,0,BinXor(PeekByte(a,0),PeekByte(mem,1023))
        Case 4
            PokeByte a,0,PeekByte(a,0)+PeekByte(mem,1023)
        Case 5
            PokeByte a,0,PeekByte(a,0)-PeekByte(mem,1023)
        Case 8
            PokeByte a,0,PeekByte(mem,1023)
        Case 9
            PokeByte mem,PeekByte(mem,1023),PeekByte(a,0)
        Case 12
            PokeByte a,0,PeekByte(mem,PeekByte(mem,1023))
    EndSelect
    
    Goto endi2
    endi:
    'PokeShort pc,0,PeekShort(pc,0)+1 Lisää laskuria
    endi2:
    cyclecount=cyclecount+1
If isrunning=True Then Goto cycle
endtime=Timer()-starttime
Print cyclecount+" cycles took "+endtime
Print PeekByte(mem,50)
Print PeekByte(mem,51)
Print PeekByte(mem,52)
WaitKey
End


Function BinAnd(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) And ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinNot(luku1)
    For i = 0 To 31
        luku3 = luku3 + (Not ((luku1 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinXor(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Xor ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinOr(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Or ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Projekteihin, koska muokkaan tämän joskus ihan oikeaksi virtuaalikoneeksi.
Ohjelmat ja tieto täytyy mahtua 255 tavuun, vaikka alussa varataaankin 1 kilotavu.
<Ize> Pitäs tehä allekirjotus..
<Ize> Vois keksiä jonkin nasahtavan sanonnan..
<Ize> Siitä tulis upea legenda ja kaikki vaihtaisivat allekirjoituksensa siihen.
<Ize> Ehkä ei kuitenkaa...

User avatar
MetalRain
Active Member
Posts: 188
Joined: Sun Mar 21, 2010 12:17 pm
Location: Espoo

Re: Tavukoodia ja virtuaalikone(hko)

Post by MetalRain » Thu Aug 02, 2012 9:56 pm

Ihan mielenkiintoinen systeemi, lähinnä vaivasi tuo pelkkien tavujen käsittely ja päätin heittää suosiolla shorteiksi. Toisaalta myös ohjelman lataaminen yksittäisiä mempoke käskyjä käyttäen on aika ikävää joten siihenkin piti saada parempi käsittely. Muuten aikalailla esikuvalleen uskollinen ohjelma tässä:

Code: Select all

Const BREAK     = 0
Const ORA       = 1  
Const ANDA      = 2  
Const XORA      = 3
Const ADD       = 4
Const SUB       = 5
Const INC       = 6
Const DEC       = 7
Const LOAD      = 8
Const STORE     = 9
Const APC       = 10
Const PCA       = 11
Const COPY      = 12
Const NOP       = 255

Dim name(256) As String 
name(0) = "BREAK"
name(1) = "ORA"
name(2) = "ANDA"
name(3) = "XORA"
name(4) = "ADD"
name(5) = "SUB"
name(6) = "INC"
name(7) = "DEC"
name(8) = "LOAD"
name(9) = "STORE"
name(10) = "APC"
name(11) = "PCA"
name(12) = "COPY"
name(255) = "NOP"

Const DEBUG = 1

Global mem

mem = MakeMEMBlock(2^16)

LoadProg("LOAD 5 STORE 50 INC STORE 52 INC STORE 54 COPY 50 STORE 0 BREAK")

RunProg() 

Print PeekShort(mem,0)
Print PeekShort(mem,50)
Print PeekShort(mem,52)
Print PeekShort(mem,54)

WaitKey



Function LoadProg(code$) 
    
    memcounter = 0
    
    For i=1 To CountWords(code$)
    
        word$ = GetWord(code$,i," ")
        
        isOP = False
        
        For o=0 To 255 
            
            If ( word$ = name(o) And word$ <> "") Then 
            
                PokeShort mem, memcounter, o
                isOP = True
                Exit
            
            EndIf 
        
        Next o
        
        If Not isOP Then 
            PokeShort mem, memcounter,Abs(Int(word$)) 
        EndIf 
        
        memcounter = memcounter + 2
        
    Next i 

End Function 

Function RunProg() 

    FINISH = 0
    PC = 0
    A = 0
    ADDR = 0
    
    While Not FINISH
    
       // cycle = Timer()
    
        OP = PeekShort(mem,PC)
        
        If DEBUG and OP < 256 Then Print name(OP)+" @ "+PC 
        
        If ( OP = BREAK ) Then
        
            FINISH = True 
            
        ElseIf ( OP = ORA) Then 
            
            PC = PC + 2
            ADDR = PeekShort(mem,PC)
            A = BinOr(A,PeekShort(mem,ADDR))
        
        ElseIf ( OP = ANDA) Then
        
            PC = PC + 2
            ADDR = PeekShort(mem,PC)
            A = BinAnd(A,PeekShort(mem,ADDR))
        
        ElseIf ( OP = XORA) Then
        
            PC = PC + 2
            ADDR = PeekShort(mem,PC)
            A = BinXor(A,PeekShort(mem,ADDR))
        
        ElseIf ( OP = ADD) Then
        
            PC = PC + 2
            VAL = PeekShort(mem,PC)
            A = A+VAL
        
        ElseIf ( OP = SUB) Then
        
            PC = PC + 2
            VAL = PeekShort(mem,PC)
            A = A-VAL
        
        ElseIf ( OP = INC) Then
        
            A = A+1
            
        ElseIf ( OP = DEC) Then
        
            A = A-1
            
        ElseIf ( OP = LOAD) Then
        
            PC = PC + 2
            VAL = PeekShort(mem,PC)
            A = VAL
        
        ElseIf ( OP = STORE) Then
        
            PC = PC + 2
            ADDR = PeekShort(mem,PC)
            PokeShort mem, ADDR, A
        
        ElseIf ( OP = APC) Then
        
            A = PC + 2
        
        ElseIf ( OP = PCA) Then
        
            PC = A
            
        ElseIf ( OP = COPY) Then
        
            PC = PC + 2
            ADDR = PeekShort(mem,PC)
            A = PeekShort(mem,ADDR)
        
        ElseIf ( OP = NOP) Then 
        
            // do nothing
            
        EndIf 
        
        PC = PC + 2
    
       // If DEBUG Then Print "Took "+(Timer()-cycle)+" ms"
    
    Wend 

End Function 

Function BinAnd(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) And ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinNot(luku1)
    For i = 0 To 31
        luku3 = luku3 + (Not ((luku1 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinXor(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Xor ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function

Function BinOr(luku1, luku2)
    For i = 0 To 31
        luku3 = luku3 + (((luku1 Shr i) Mod 2) Or ((luku2 Shr i) Mod 2)) Shl i
    Next i
    Return luku3
End Function
Useampi rekisteri ja muutamat kontrollirakenteet auttaisivat tällä minkään järkevän koodausta. Sitten jos tosiaan muisti ja rekisterit on kaikki muistipaloissa voisi tuota koko virtuaalikonettakin pitää yhdessä muistipalassa. Tällöin voisi näppärästi päästä vuorottelemaan ajettavilla ohjelmilla ja näin ajamaan "rinnan" montaa eri konetta ja/tai ohjelmaa. Siitä voisi jo jonkinlaisen pelinkin kyhätä.
Last edited by MetalRain on Thu Aug 02, 2012 10:45 pm, edited 2 times in total.

User avatar
naputtelija
Devoted Member
Posts: 718
Joined: Wed Nov 03, 2010 8:56 pm
Location: Joku piste pohjoisessa.

Re: Tavukoodia ja virtuaalikone(hko)

Post by naputtelija » Thu Aug 02, 2012 10:41 pm

Tarkoituksena on siis luoda virtuaalikone eikä välttämättä assembleria. Mutta hienon assemblerin värkkäsit. Eli haluan pyörittää käyttöjärjestelmää virtuaalikoneen natiiveilla.
EDIT:

Sitäpaitsi virtuaalikonetta tehdessä kannattaa tehdä mahdollisimman nopea. siksi välttelen muita kuin natiivikomentoja.

<Ize> Pitäs tehä allekirjotus..
<Ize> Vois keksiä jonkin nasahtavan sanonnan..
<Ize> Siitä tulis upea legenda ja kaikki vaihtaisivat allekirjoituksensa siihen.
<Ize> Ehkä ei kuitenkaa...

Post Reply