From 61bb14b9e36e952a9e6e3b606e2a84453881fbb1 Mon Sep 17 00:00:00 2001 From: Jaka Furlan Date: Sat, 29 Nov 2025 21:17:09 +0100 Subject: [PATCH] working...1 --- ass2/SICocaml/izvajalnik.cmi | Bin 3169 -> 3174 bytes ass2/SICocaml/izvajalnik.cmo | Bin 11085 -> 12039 bytes ass2/SICocaml/izvajalnik.ml | 19 +- ass2/SICocaml/izvajalnikF3.ml | 2 +- ass2/SICocaml/izvajalnikF4.ml | 2 +- ass2/SICocaml/sicxeDune/bin/dune | 4 + ass2/SICocaml/sicxeDune/bin/main.ml | 37 +++ ass2/SICocaml/sicxeDune/dune-project | 26 ++ ass2/SICocaml/sicxeDune/lib/decoder.ml | 10 + ass2/SICocaml/sicxeDune/lib/dune | 3 + ass2/SICocaml/sicxeDune/lib/izvajalnik.ml | 272 ++++++++++++++++++ ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml | 12 + ass2/SICocaml/sicxeDune/lib/izvajalnikF2.ml | 59 ++++ ass2/SICocaml/sicxeDune/lib/izvajalnikF3.ml | 155 ++++++++++ ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml | 155 ++++++++++ ass2/SICocaml/sicxeDune/lib/opcodeTable.ml | 163 +++++++++++ ass2/SICocaml/sicxeDune/lib/processor.ml | 111 +++++++ ass2/SICocaml/sicxeDune/sicxeDune.opam | 32 +++ ass2/SICocaml/sicxeDune/test/dune | 2 + .../SICocaml/sicxeDune/test/test_sicxeDune.ml | 0 ass2/SICocaml/test.ml | 2 +- 21 files changed, 1054 insertions(+), 12 deletions(-) create mode 100644 ass2/SICocaml/sicxeDune/bin/dune create mode 100644 ass2/SICocaml/sicxeDune/bin/main.ml create mode 100644 ass2/SICocaml/sicxeDune/dune-project create mode 100644 ass2/SICocaml/sicxeDune/lib/decoder.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/dune create mode 100644 ass2/SICocaml/sicxeDune/lib/izvajalnik.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/izvajalnikF2.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/izvajalnikF3.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/opcodeTable.ml create mode 100644 ass2/SICocaml/sicxeDune/lib/processor.ml create mode 100644 ass2/SICocaml/sicxeDune/sicxeDune.opam create mode 100644 ass2/SICocaml/sicxeDune/test/dune create mode 100644 ass2/SICocaml/sicxeDune/test/test_sicxeDune.ml diff --git a/ass2/SICocaml/izvajalnik.cmi b/ass2/SICocaml/izvajalnik.cmi index b1c4bff8faaa8be6730ca1ca9a6a846391a76b81..9627cf131c383f819a1e46aa49b3bae3fd72aa25 100644 GIT binary patch delta 327 zcmaDT@k~O&IWafK(9+V<)4Zgmel?8|&kvw@E(4g&%Ql&l zy-qlfk>81t-wi0<#Qf!` zRHDb=z{mk)r%b-U+AHkE$a$2J^E6Q0j{(BII=O(YQ#hKD=RPCPW1x601BCr?G7o#5 za3&+)ZbrWSK=CdH2>a~hx$HAV7-|^>w=)Xv21=}fvQJL-;g}<`g;DZ1qvU^}_&G)f zFh`1a@*j>Sk(Z2$^^A(mK#A9k3=q!b$&)xkL>ay?D*G@h2OMB!Vqk=F!YBXc)D;LY ZHqM$O@hf5O+zG9viT=MfTX5+y0RT~fUM&Cs diff --git a/ass2/SICocaml/izvajalnik.cmo b/ass2/SICocaml/izvajalnik.cmo index 7038042cd50310b30ef224a73d9a52eea3e6ec2f..c0d8363046d75cdf2fc4f2d1d7ddc61f7dfe248b 100644 GIT binary patch delta 3413 zcmZWr4RBP|6~5p5*(96&OS0MQCXg)oCtyiJfI^W8B*X+0LrE;C{0L-~00~GCBMvSi z(9lvQ%L{^4V4Yg4Em%xwhtif=rk(Orsi;`#5R0~*wZS6*s2S$*w~+*^+x$hWnd_2mp(9< zl+Z&d^j{tg9}SI$hekS$6r&<}l+I5g1H0WdicytZXe83LfkAKFf$7G&Ko(v!b_5Eh zj=FK{mYe*%R;0_aoMjXZ&T;sEw{AJf+W+ya{GUqWapNlG@)#*u`||_KgwQ`C1>=NB zYe*KNRFpNWU9)iM!sVUq%Vr|jZJf<&_CrI_>nJ*s&=gqs6XQFhY4*BVB*h=!BCg~zbNr&MD>~a3PYNHPpnQm<$QeY= z6(R)|88*q7lov;paV~FsRJl$WbWqA060C(9B(Qz-SBtKzf=17Jd;5!~*4EaI<-|`y z9K*277)~dMwKj2)G;K6X@<6L+n+B~-h8EW}H_bF-dmv6?cm%^YB=jh@*sOGYY=}&I1S;uNaxRO zQb|+k%h@&BU)X3ZsUPAz!c_=2lk0#@TG(|x&vFm+7un8$eu!-o^fPQ{LjP3GTG%+V zrHVJ_7{n05UtmO#$Z?wtqf8E|doCPO_X0SgQurb`NO(+(z_FU`5;%Izg|xKR)XSXb zA^wdKt1x04<^0el2IqX)oV}&BPI_L1xQG!uFoLCAvdKaAl)Bf!A$6~Zt}JTo9*` z+lt&yB5s>J#*RId`^)mGpr)!DizIUm1+&fQY>2m!+lAa8QFM+?dO7-#@!i~ls6w@T z75OJokVPJaHmP6_E)^Zuk#tsqKOl*UhNP9+t-<;#t&sc=h>W$#1&;q*hP{PkA;CLH z_AyXWki3x+y;L24$+(s~CaBay`~Vr-kgLFLVk(9qeL|;WP1;IjceILRkrR*x}{v=Xm*`Gq{9G>koQmJ}k z+Pg?K%iiuJBXmLVUsfJCmgmSuS&4pNQToBe00b-8PAE$Q;>3>U4<1$li-=dON6f z7Rhn22Um%%2H@^ypj?2vN9wt~iPTm*zMtanx5;6S-zCGY!X203I@||j#!>JjQzEO0 z@}^XN?Tw`_6_3Gt3SR0e@@=I`U-rS1dqe#|K=GD z*&%dAs26OqfZ~0HGVB@nMoX{}K3=-6-hi)-fJ0Z0z}L+m785JJeoSA81#qu}n=WYe zriFiV+c7o9dt)=`#Eb_*!;CRGj_@5Bin^SdpCwRH(S(=a>y<06pxx23MLRqRc-@3^ zEX*C@Gb`vae7}=Xhv9qk8|&3Znh~CNDZ0$U=Qx`02VMOWd_xkPfbTkiI}SQpfi$`; z_@vY7W$J?ZhGy1OEh6wtf#(6jQ!PA~vZl?IZiV+X&uU`72Jr|y^Wj-bc!q_aX1|qY zx)w9tEb%Bj>*0BU+*&NWhi~n)jiz6#>GzOW0#6*C-;&>43m@Thvc0qpq*GnRbZsRv z$V(1VOuCHNuy$r5aXUv`cbgMW#9(g*)~33ej0+_vPK z2X!;l*J;A%jCI9j<1=ZUG{FdQ|&$D!IFn7GXE%pjv|xG#-203^KPE* zvnGhm5IYI}$ArI@U*X16*_(`>(sAPhL5|kHjQ}l|>bju(TjdBe(!=d{wXAMi-o9wT zf@x2#j&vc=7msh>uIn2RTs?5D^lfCE>@DBz95>;_y;J5N9#+?T^HS;)#`|TBW%|yz g4kNBB;kd3IitE~gah;#(f1?qJYm3SJw3>ha2ax3#GXMYp delta 3113 zcmZWr4RBP|6~5p5*-iF8n+>~57B;X;3JKCcC?pQf1QH=oVs=bGN1_mtI0OTvRcYuT z3l&fpreyQ1I%9xUsnVa&NT^5$+eoqFRB(WzP>2d0X=%km)sc~AO3%6PJ&GkWcg}Zi z&Ufy2?>*^1uR#w)Rm6r(-?r#)A+^-AKVmy%_eyyxi855(KF*IB> zyw(^^R-=)i@yNg^H34JDA23qd49j|qJ=z(<9%GxHb91g=Uv?8ub!@!t|Cb!u+veVI zhU~e4^UjC^%Liuqs+EEMK(7NSqb?lAL8C347*#ub;|A;V(+JY=&?u#$(zt5$g$tv< zxPIdX@4`nTK*RoTjd3B|H#UEZ5ISwtKSU#%BgA-7GWUn8o0m6ttZaWIg>csBkJN|6 zH6%Vl;-7<>0uv|WMt<~MNDL!+5XpB3wYy>AYlbp%SH6mIpP@J~sI3M}Tx{$g`Do}e z#(FV!)S&h}gozi;G~OzW7;lztGCm!bXZ*czUHV^0ry6p3dEZzd=`ZRL@u|TgGAP1Od18Pf^8ABMz#rPootJtZDTtD+8(wO zp&eoSZD{A&PJuRT>YQIwT`P4qK%BtnSs49Ln$~Kxy%t(a56IZ$d}~Wh5GOIZ4Wrjn zUc3SSQg3D0Ox!qLxmGaN_RZh_+x+ih@amWlg*#MV*ny|(itrFN2V5}atPk>~z8#P1Q?gxD?$JiyKz_Fm%1iIn^s^;Hh1xrfAk zCi@7)5yW;Q_FH1VZ98uDI(EXjR)Q69QqhpK z@pUWPR;*gt-ojTjWK(?Pd}uo(nBOaDYv9~1!CE-?OE7?(@s#Mrs_cu#bFsMbk1^gt zPW3s&1_ak3_+xUuu$>{}qga+=D$*6qRszW3>d}>X$dR|O3Ato%Z7O9B#8b%cNB+@4 zU8%L56C^5E)_(@Mvi_ez?jA`kzS&dCLWr#hl^`^SxcAu(m0TLRhiG9fi`+A8Uq~)sDkWg_P0$1h?4%$@yke zDL;YOjqqWFKcr00+Rg>awo{y<{tA&nK?Mr#CFgIpvw$hX)KAIu6^Pdm-HzxG1zfeAuPDIF zMWQQ%@Wv$A4lk7p$+@+il>gY2mxzDEc7D$M8Itw_yfqT+gtw7_Is)G33CM>aZG9SN zPk}E)lbQ}+8QUEA_zX2Se4T84@O87zgRh@$2)^TN!|+{YI}-kYR5y0^6zWa&4zU`6 zE68&Zo@8MUsq!Z|x)^@yN!p9?aM8%LBvgtn9)^(&X)=e_Id68HyYnmZphmK8 zWZ^7lIWIY-@L!hcuES5Y_kUNRwp)z(#9nUUMq&p%lI=i%PgqxT5#U4k#zUN*i~#SC z&Ogv4QzvTY*0ZMdVhOwl;5|urgN5JctlMN*@}By8>o{(UXomMRyk8LBYGHmD=vHJ6 zH<;;q#8P;_rpu-Mc5IS@V>07HhTUNEU74ZRHZh}g`x7rAPW^6B6;0~RVl#dY_GOmRN#jDqS)m^d$#qK!~e>KTj-V?8>_+oi?owVl%{Z1g9H2O3zL!sFl%OD4-p6 zcN>YaNo6QlOOri!G(6VY(Y|!?;#q4RYkL$0N3z+T9$lj+w|Ag#B5mE(U6v{@U)~$J wzGTOa?oE$3*Izd>ljfIbr?d1+gT`=HSMQ;5HLLTS9wqzJtky#2Vio`W7bc?2@Bjb+ diff --git a/ass2/SICocaml/izvajalnik.ml b/ass2/SICocaml/izvajalnik.ml index 065624d..1ff702c 100644 --- a/ass2/SICocaml/izvajalnik.ml +++ b/ass2/SICocaml/izvajalnik.ml @@ -39,7 +39,7 @@ let readR1R2 (state : Processor.state) : (int * int) = (highNibble, lowNibble) (*preberi byta 1 in 2 in dobi nixbpe bite*) -let getNIXBPE (state : Processor.state) : nixbpe = +let readNIXBPE (state : Processor.state) : nixbpe = let byte1 = Char.code (Processor.readMem state 0) in let byte2 = Char.code (Processor.readMem state 1) in {n = (byte1 lsr 1) land 1; @@ -52,7 +52,7 @@ let getNIXBPE (state : Processor.state) : nixbpe = (*dobi disp iz tipa ukaza 3*) (*TODO pretvori v negativno število glede na nxibpe*) -let getDisp (state : Processor.state) : int = +let readDisp (state : Processor.state) : int = let byte2 = Char.code (Processor.readMem state 1) in let byte3 = Char.code (Processor.readMem state 2) in let disp_high = byte2 land 0x0F in @@ -61,7 +61,7 @@ let getDisp (state : Processor.state) : int = (*dobi address iz tip ukaza 4*) (*TODO preveri ali mores paziti negativnost*) -let getAddress (state : Processor.state) : int = +let readAddress (state : Processor.state) : int = let byte2 = Char.code (Processor.readMem state 1) in let byte3 = Char.code (Processor.readMem state 2) in let byte4 = Char.code (Processor.readMem state 3) in @@ -71,7 +71,8 @@ let getAddress (state : Processor.state) : int = let address = (addr_high lsl 8) lor byte4 in address - let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int = +(*pridobi operand*) +let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int = let ea = if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*) else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp (*PC relativno*) @@ -131,7 +132,7 @@ let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : (*execute Format 3*) let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = - let disp = getDisp state in + let disp = readDisp state in let operand = getOperand state nixbpe disp in (*debugging*) Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n" @@ -158,7 +159,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode | JGT -> IzvajalnikF3.jgt state operand | JLT -> IzvajalnikF3.jlt state operand | JSUB -> IzvajalnikF3.jsub state operand - | RSUB -> IzvajalnikF3.rsub state operand + | RSUB -> IzvajalnikF3.rsub state (* Load/store *) | LDA -> IzvajalnikF3.lda state operand @@ -186,7 +187,7 @@ let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = - let address = getAddress state in + let address = readAddress state in let operand = getOperand state nixbpe address in (*debugging*) Printf.printf "[Izvajalnik/executeFormat4] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n" @@ -213,7 +214,7 @@ let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode | JGT -> IzvajalnikF4.jgt state operand | JLT -> IzvajalnikF4.jlt state operand | JSUB -> IzvajalnikF4.jsub state operand - | RSUB -> IzvajalnikF4.rsub state operand + | RSUB -> IzvajalnikF4.rsub state (* Load/store *) | LDA -> IzvajalnikF4.lda state operand @@ -243,7 +244,7 @@ let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: Opcode (*execute format 3_4*) let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = - let nixbpe = getNIXBPE state in + let nixbpe = readNIXBPE state in (*debugging*) Printf.printf "[Izvajalnik/executeFormat3_4]n=%d,i=%d,x=%d,b=%d,p=%d,e=%d\n" nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e; diff --git a/ass2/SICocaml/izvajalnikF3.ml b/ass2/SICocaml/izvajalnikF3.ml index 80db3e8..ef18827 100644 --- a/ass2/SICocaml/izvajalnikF3.ml +++ b/ass2/SICocaml/izvajalnikF3.ml @@ -70,7 +70,7 @@ let jsub (state : Processor.state) (operand : int) : unit = state.regs.pc <- operand (*PC <- (L)*) -let rsub (state : Processor.state) (operand : int) : unit = +let rsub (state : Processor.state) : unit = state.regs.pc <- state.regs.l (*A <- (m..m+2)*) diff --git a/ass2/SICocaml/izvajalnikF4.ml b/ass2/SICocaml/izvajalnikF4.ml index 80db3e8..ef18827 100644 --- a/ass2/SICocaml/izvajalnikF4.ml +++ b/ass2/SICocaml/izvajalnikF4.ml @@ -70,7 +70,7 @@ let jsub (state : Processor.state) (operand : int) : unit = state.regs.pc <- operand (*PC <- (L)*) -let rsub (state : Processor.state) (operand : int) : unit = +let rsub (state : Processor.state) : unit = state.regs.pc <- state.regs.l (*A <- (m..m+2)*) diff --git a/ass2/SICocaml/sicxeDune/bin/dune b/ass2/SICocaml/sicxeDune/bin/dune new file mode 100644 index 0000000..a16b16a --- /dev/null +++ b/ass2/SICocaml/sicxeDune/bin/dune @@ -0,0 +1,4 @@ +(executable + (public_name sicxeDune) + (name main) + (libraries sicxeDune)) diff --git a/ass2/SICocaml/sicxeDune/bin/main.ml b/ass2/SICocaml/sicxeDune/bin/main.ml new file mode 100644 index 0000000..d3231ef --- /dev/null +++ b/ass2/SICocaml/sicxeDune/bin/main.ml @@ -0,0 +1,37 @@ +(* test_execute.ml *) + +open Processor (* assuming your state, regs, and execute are defined here *) + +(* Test function *) +let test_execute () = + (* Create a dummy state *) + let mem_size = 1024 in + let memory = Bytes.make mem_size '\000' in + let regs = { + a = 0; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0; + pc = 0; sw = 0 + } in + let state = { memory; regs } in + + (* Example: Write a LDA instruction at address 0*) + Processor.write_instruction3 state 0 '\x01' '\x00' '\x23'; + + (* Write the operand value at 0x010 *) + Processor.writeMemAddr state 0x010 0x123456; + + (* Set PC to 0 *) + state.regs.pc <- 0; + + Printf.printf "Before execution:\n"; + Processor.print_regs state; + Processor.print_memory state 15; + + (* Execute instruction *) + Izvajalnik.execute state; + + Printf.printf "After execution:\n"; + Processor.print_regs state; + Processor.print_memory state 15 + +(* Run the test *) +let () = test_execute () diff --git a/ass2/SICocaml/sicxeDune/dune-project b/ass2/SICocaml/sicxeDune/dune-project new file mode 100644 index 0000000..b30c54a --- /dev/null +++ b/ass2/SICocaml/sicxeDune/dune-project @@ -0,0 +1,26 @@ +(lang dune 3.20) + +(name sicxeDune) + +(generate_opam_files true) + +(source + (github username/reponame)) + +(authors "Author Name ") + +(maintainers "Maintainer Name ") + +(license LICENSE) + +(documentation https://url/to/documentation) + +(package + (name sicxeDune) + (synopsis "A short synopsis") + (description "A longer description") + (depends ocaml) + (tags + ("add topics" "to describe" your project))) + +; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html diff --git a/ass2/SICocaml/sicxeDune/lib/decoder.ml b/ass2/SICocaml/sicxeDune/lib/decoder.ml new file mode 100644 index 0000000..7955cc3 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/decoder.ml @@ -0,0 +1,10 @@ +(*decoderjeva naloga je pridobiti mnemonic in tip ukaza iz prvega byta z pogledom v hash-table*) +let table = OpcodeTable.table + +let decoder (byte1 : char) : OpcodeTable.info = + let opcode = (Char.code byte1) land 0xFC in + try + Hashtbl.find OpcodeTable.table opcode + with + | Not_found -> failwith "invalid opcode" + diff --git a/ass2/SICocaml/sicxeDune/lib/dune b/ass2/SICocaml/sicxeDune/lib/dune new file mode 100644 index 0000000..2f1c957 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/dune @@ -0,0 +1,3 @@ +(library + (name sicxeDune) + (wrapped false)) diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml new file mode 100644 index 0000000..1ff702c --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnik.ml @@ -0,0 +1,272 @@ +open OpcodeTable + +type nixbpe = { + n : int; + i : int; + x : int; + b : int; + p : int; + e : int +} + +let string_of_nixbpe nixbpe = + Printf.sprintf "n=%d,i=%d,x=%d,b=%d,p=%d,e=%d" + nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e + +(*kreiramo začetno stanje -> TODO prestavi v main*) +let regs = Processor.{a = 0; x = 0; l = 0; b = 0; s = 0; t = 0; f = 0.0; pc = 0; sw = 0} +let memSize = 1 lsl 20 (*2^20*) +let memory = Bytes.make memSize '\x00' (*mutbale kos pomnilnika velikosti memSize*) +let state = Processor.{regs; memory} + + +(*----Funkcije izvajalnika----*) +(*TODO - brali bomo vedno relativno od začetka instrukcije, PC bomo na koncu ukaza povečali za pravo velikost!*) + +(*funkcije za javljanje napak*) +let notImplemented (mnemonic : string) = Printf.printf "mnemonic %s is not implemented!\n" mnemonic +let invalidOpcode (opcode : int) = Printf.printf "opcode %d is invalid!\n" opcode +let invalidAdressing () = Printf.printf "invalid adressing!\n" + + + + +(*beri drugi byte ukaza formata 2 in vrni r1 in r2, kot int njunih vrednosti (reg a -> 1, reg x -> 2 ...)*) +let readR1R2 (state : Processor.state) : (int * int) = + let byte2 = Char.code (Processor.readMem state 1) in + let highNibble = (byte2 land 0xF0) lsr 4 in (*pridobi prvi nibble*) + let lowNibble = byte2 land 0x0F in (*pridobi drugi nibble*) + (highNibble, lowNibble) + +(*preberi byta 1 in 2 in dobi nixbpe bite*) +let readNIXBPE (state : Processor.state) : nixbpe = + let byte1 = Char.code (Processor.readMem state 0) in + let byte2 = Char.code (Processor.readMem state 1) in + {n = (byte1 lsr 1) land 1; + i = byte1 land 1; + x = (byte2 lsr 7) land 1; + b = (byte2 lsr 6) land 1; + p = (byte2 lsr 5) land 1; + e = (byte2 lsr 4) land 1;} + + +(*dobi disp iz tipa ukaza 3*) +(*TODO pretvori v negativno število glede na nxibpe*) +let readDisp (state : Processor.state) : int = + let byte2 = Char.code (Processor.readMem state 1) in + let byte3 = Char.code (Processor.readMem state 2) in + let disp_high = byte2 land 0x0F in + let disp = (disp_high lsl 8) lor byte3 in + disp + +(*dobi address iz tip ukaza 4*) +(*TODO preveri ali mores paziti negativnost*) +let readAddress (state : Processor.state) : int = + let byte2 = Char.code (Processor.readMem state 1) in + let byte3 = Char.code (Processor.readMem state 2) in + let byte4 = Char.code (Processor.readMem state 3) in + + let addr_highest = byte2 land 0x0F in + let addr_high = (addr_highest lsl 8) lor byte3 in + let address = (addr_high lsl 8) lor byte4 in + address + +(*pridobi operand*) +let getOperand (state : Processor.state) (nixbpe : nixbpe) (disp : int) : int = + let ea = + if nixbpe.b = 1 && nixbpe.p = 0 then state.regs.b + disp (*B relativno*) + else if nixbpe.p = 1 && nixbpe.b = 0 then state.regs.pc + disp (*PC relativno*) + else disp (*direktno*) + in + let ea = if nixbpe.x = 1 then ea + state.regs.x else ea in (*+ (X) po potrebi*) + (*pridobi operand*) + let value = + if nixbpe.n = 1 && nixbpe.i = 1 then Processor.readMemAddr state ea (*direktno*) + else if nixbpe.n = 0 && nixbpe.i = 1 then disp (* immediate value *) + else if nixbpe.n = 1 && nixbpe.i = 0 then Processor.readMemAddr state (Processor.readMemAddr state ea) (* indirect *) + else failwith "Invalid addressing mode" + in + value + +(*execute format 1*) +let executeFormat1 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = + Processor.pcIncrement state 1; + (*debugging*) + Printf.printf "[Izvajalnik/executeFormat1] Mnemonic: %s\n" + (string_of_mnemonic mnemonic); + + match mnemonic with + | FIX -> IzvajalnikF1.fix state + | FLOAT -> IzvajalnikF1.floatF state + | HIO -> notImplemented "HIO" + | NORM -> notImplemented "NORM" + | SIO -> notImplemented "SIO" + | TIO -> notImplemented "TIO" + |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 1") + + + +(*execute format 2*) +let executeFormat2 (state: Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = + let (r1, r2) = readR1R2 state in + (*debugging*) + Printf.printf "[Izvajalnik/executeFormat2] Mnemonic: %s, r1: %d, r2: %d\n" + (string_of_mnemonic mnemonic) r1 r2; + + Processor.pcIncrement state 2; + match mnemonic with + | ADDR -> IzvajalnikF2.addr state r1 r2 + | CLEAR -> IzvajalnikF2.clear state r1 + | COMPR -> IzvajalnikF2.compr state r1 r2 + | DIVR -> IzvajalnikF2.divr state r1 r2 + | MULR -> IzvajalnikF2.mulr state r1 r2 + | RMO -> IzvajalnikF2.rmo state r1 r2 + | SHIFTL -> IzvajalnikF2.shiftl state r1 r2 + | SHIFTR -> IzvajalnikF2.shiftr state r1 r2 + | SUBR -> IzvajalnikF2.subr state r1 r2 + | SVC -> notImplemented "F2" + | TIXR -> IzvajalnikF2.tixr state r1 + |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 2") + + + +(*execute Format 3*) +let executeFormat3 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = + let disp = readDisp state in + let operand = getOperand state nixbpe disp in + (*debugging*) + Printf.printf "[Izvajalnik/executeFormat3] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n" + (string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand; + + Processor.pcIncrement state 3; (*povecamo pc pred izvedbo ukaza*) + match mnemonic with + | ADD -> IzvajalnikF3.add state operand + | ADDF -> notImplemented "ADDF3" + | AND -> IzvajalnikF3.andF state operand + | COMP -> IzvajalnikF3.comp state operand + | COMPF -> notImplemented "COMPF3" + | DIV -> IzvajalnikF3.div state operand + | MUL -> IzvajalnikF3.mul state operand + | OR -> IzvajalnikF3.orF state operand + | SUB -> IzvajalnikF3.sub state operand + | SUBF -> notImplemented "SUBF3" + | TD -> notImplemented "TD3" + | WD -> notImplemented "WD3" + + (* Jump / subroutine *) + | J -> IzvajalnikF3.j state operand + | JEQ -> IzvajalnikF3.jeq state operand + | JGT -> IzvajalnikF3.jgt state operand + | JLT -> IzvajalnikF3.jlt state operand + | JSUB -> IzvajalnikF3.jsub state operand + | RSUB -> IzvajalnikF3.rsub state + + (* Load/store *) + | LDA -> IzvajalnikF3.lda state operand + | LDB -> IzvajalnikF3.ldb state operand + | LDCH -> notImplemented "LDCH3" + | LDF -> notImplemented "LDF3" + | LDL -> IzvajalnikF3.ldl state operand + | LDS -> IzvajalnikF3.lds state operand + | LDT -> IzvajalnikF3.ldt state operand + | LDX -> IzvajalnikF3.ldx state operand + | LPS -> notImplemented "LPS4" + | STA -> IzvajalnikF3.sta state operand + | STB -> IzvajalnikF3.stb state operand + | STCH -> notImplemented "STCH4" + | STF -> notImplemented "STF4" + | STL -> IzvajalnikF3.stl state operand + | STS -> IzvajalnikF3.sts state operand + | STSW -> IzvajalnikF3.stsw state operand + | STT -> IzvajalnikF3.stt state operand + | STX -> IzvajalnikF3.stx state operand + + (* Control / IO *) + | TIX -> IzvajalnikF3.tix state operand + |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3") + + +let executeFormat4 (state : Processor.state) (nixbpe : nixbpe) (mnemonic: OpcodeTable.mnemonic): unit = + let address = readAddress state in + let operand = getOperand state nixbpe address in + (*debugging*) + Printf.printf "[Izvajalnik/executeFormat4] Mnemonic: %s, nixbpe: %s, operand: %d = 0x%02X\n" + (string_of_mnemonic mnemonic) (string_of_nixbpe nixbpe) operand operand; + + Processor.pcIncrement state 3; + match mnemonic with + | ADD -> IzvajalnikF4.add state operand + | ADDF -> notImplemented "ADDF3" + | AND -> IzvajalnikF4.andF state operand + | COMP -> IzvajalnikF4.comp state operand + | COMPF -> notImplemented "COMPF3" + | DIV -> IzvajalnikF4.div state operand + | MUL -> IzvajalnikF4.mul state operand + | OR -> IzvajalnikF4.orF state operand + | SUB -> IzvajalnikF4.sub state operand + | SUBF -> notImplemented "SUBF3" + | TD -> notImplemented "TD3" + | WD -> notImplemented "WD3" + + (* Jump / subroutine *) + | J -> IzvajalnikF4.j state operand + | JEQ -> IzvajalnikF4.jeq state operand + | JGT -> IzvajalnikF4.jgt state operand + | JLT -> IzvajalnikF4.jlt state operand + | JSUB -> IzvajalnikF4.jsub state operand + | RSUB -> IzvajalnikF4.rsub state + + (* Load/store *) + | LDA -> IzvajalnikF4.lda state operand + | LDB -> IzvajalnikF4.ldb state operand + | LDCH -> notImplemented "LDCH3" + | LDF -> notImplemented "LDF3" + | LDL -> IzvajalnikF4.ldl state operand + | LDS -> IzvajalnikF4.lds state operand + | LDT -> IzvajalnikF4.ldt state operand + | LDX -> IzvajalnikF4.ldx state operand + | LPS -> notImplemented "LPS4" + | STA -> IzvajalnikF4.sta state operand + | STB -> IzvajalnikF4.stb state operand + | STCH -> notImplemented "STCH4" + | STF -> notImplemented "STF4" + | STL -> IzvajalnikF4.stl state operand + | STS -> IzvajalnikF4.sts state operand + | STSW -> IzvajalnikF4.stsw state operand + | STT -> IzvajalnikF4.stt state operand + | STX -> IzvajalnikF4.stx state operand + + (* Control / IO *) + | TIX -> IzvajalnikF3.tix state operand + |_ -> failwith ("Mnemonic" ^ (OpcodeTable.string_of_mnemonic mnemonic) ^ "falsely flaged as format 3") + + + +(*execute format 3_4*) +let executeFormat3_4 (state : Processor.state) (mnemonic : OpcodeTable.mnemonic) : unit = + let nixbpe = readNIXBPE state in + (*debugging*) + Printf.printf "[Izvajalnik/executeFormat3_4]n=%d,i=%d,x=%d,b=%d,p=%d,e=%d\n" nixbpe.n nixbpe.i nixbpe.x nixbpe.b nixbpe.p nixbpe.e; + + match nixbpe.e with + | 0 -> executeFormat3 state nixbpe mnemonic + | 1 -> executeFormat4 state nixbpe mnemonic + | _ -> failwith "invalid computation of nxbpe" + +(*execute ukaza*) +let execute (state : Processor.state) : unit = + let byte1 = Processor.readMem state 0 in (*read the 1st byte of the instruction*) + (*debugging*) + Printf.printf "[Izvajalnik/execute]Prebral byte1 %c = 0x%02X\n" byte1 (Char.code byte1); + + try + let info = Decoder.decoder byte1 in (*determen the format of the instruction from the 1st byte*) + (*debugging*) + Printf.printf "[Izvajalnik/execute]Opcode %s, format %s\n" (string_of_mnemonic info.mnemonic) (format_str info.format); + + match info.format with + | F1 -> executeFormat1 state info.mnemonic + | F2 -> executeFormat2 state info.mnemonic + | F3_4 -> executeFormat3_4 state info.mnemonic + with + | Failure msg -> Printf.printf "Cought faliure %s \n" msg; \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml new file mode 100644 index 0000000..4a569c0 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnikF1.ml @@ -0,0 +1,12 @@ +(*A <- (F) [convert to integer]*) +let fix (state : Processor.state) : unit = + state.regs.a <- int_of_float state.regs.f; + () + +(*F <- (A) [convert to floating]*) +let floatF (state : Processor.state) : unit = (*poimenovana floatF zaradi tipa float*) + state.regs.f <- float_of_int state.regs.a; + () + +(*TODO implement the rest*) + diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnikF2.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnikF2.ml new file mode 100644 index 0000000..e1e7378 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnikF2.ml @@ -0,0 +1,59 @@ +(*r2 <- (r2) + (r1)*) +let addr (state : Processor.state) (r1 : int) (r2 : int) : unit = + let valR1 = Processor.read_register_int state r1 in + let valR2 = Processor.read_register_int state r2 in + Processor.write_register_int state r2 (valR1 + valR2) + +(*r1 <- 0*) +let clear (state : Processor.state) (r1 : int) : unit = + Processor.write_register_int state r1 0 + + (*(r1):(r2)*) +let compr (state : Processor.state) (r1 : int) (r2 : int) : unit = + let sw = 9 in + let valR1 = Processor.read_register_int state r1 in + let valR2 = Processor.read_register_int state r2 in + Processor.write_register_int state sw (if valR1 < valR2 then 0 else if valR1 = valR2 then 1 else 2) + +(*r2 <- (r2) / (r1)*) +let divr (state : Processor.state) (r1 : int) (r2 : int) : unit = + let valR1 = Processor.read_register_int state r1 in + let valR2 = Processor.read_register_int state r2 in + Processor.write_register_int state r2 (valR2 / valR1) + +(*r2 <- (r2) * (r1)*) +let mulr (state : Processor.state) (r1 : int) (r2 : int) : unit = + let valR1 = Processor.read_register_int state r1 in + let valR2 = Processor.read_register_int state r2 in + Processor.write_register_int state r2 (valR2 * valR1) + +(*r2 <- (r1)*) +let rmo (state : Processor.state) (r1 : int) (r2 : int) : unit = + let valR1 = Processor.read_register_int state r1 in + Processor.write_register_int state r2 (valR1) + +(*r1 <- (r1); left shift n bits. {In assembled instruction, r2 = n-1}*) +let shiftl(state : Processor.state) (r1 : int) (r2 : int) = + let n = r2 + 1 in + let valR1 = Processor.read_register_int state r1 in + Processor.write_register_int state r1 (valR1 lsl n) + +(*r1 <- (r1); right shift logical n bits. {In assembled instruction, r2 = n-1}*) +let shiftr(state : Processor.state) (r1 : int) (r2 : int) = + let n = r2 + 1 in + let valR1 = Processor.read_register_int state r1 in + Processor.write_register_int state r1 (valR1 lsr n) + +(*r2 <- (r2) - (r1)*) +let subr (state : Processor.state) (r1 : int) (r2 : int) : unit = + let valR1 = Processor.read_register_int state r1 in + let valR2 = Processor.read_register_int state r2 in + Processor.write_register_int state r2 (valR2 - valR1) + +(*X <- (X) + 1; (X):(r1)*) +let tixr (state : Processor.state) (r1 : int) : unit = + state.regs.x <- state.regs.x + 1; + let sw = 9 in + let valR1 = Processor.read_register_int state r1 in + let valX = state.regs.x in + Processor.write_register_int state sw (if valX < valR1 then 0 else if valX = valR1 then 1 else 2) \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnikF3.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnikF3.ml new file mode 100644 index 0000000..ef18827 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnikF3.ml @@ -0,0 +1,155 @@ +(*A <- (A)+ (m..m+2)*) +let add (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA + operand + +(*F (F) + (m..m+5)*) +(*TODO check!*) +let addf (state : Processor.state) (operand : int) : unit = + let valF = state.regs.f in + state.regs.f <- valF +. (float_of_int operand) + +(*A <- (A) & (m..m+2)*) +let andF (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA land operand + +(*(A):(m..m+2)*) +let comp (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.sw <- (if valA < operand then 0 else if valA = operand then 1 else 2) + +(*A <- (A) / (m..m+2)*) +let div (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA / operand + +(*A <- (A) * (m..m+2)*) +let mul (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA * operand + +(*A <- (A) | (m..m+2)*) +let orF (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA lor operand + +(*A <- (A) - (m..m+2)*) +let sub (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA - operand + +(*PC <- m*) +let j (state : Processor.state) (operand : int) : unit = + state.regs.pc <- operand + +(*PC <- m if CC set to =*) +let jeq (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 1 -> state.regs.pc <- operand + | _ -> () + +(*PC <- m if CC set to >*) +let jgt (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 2 -> state.regs.pc <- operand + | _ -> () + +(*PC <- m if CC set to <*) +let jlt (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 0 -> state.regs.pc <- operand + | _ -> () + +(*L <- (PC); PC <- m*) +let jsub (state : Processor.state) (operand : int) : unit = + state.regs.l <- state.regs.pc; + state.regs.pc <- operand + +(*PC <- (L)*) +let rsub (state : Processor.state) : unit = + state.regs.pc <- state.regs.l + +(*A <- (m..m+2)*) +let lda (state : Processor.state) (operand : int) : unit = + state.regs.a <- operand + +(* LDB: B <- (m..m+2) *) +let ldb (state : Processor.state) (operand : int) : unit = + state.regs.b <- operand + +(*A [rightmost byte] ← (m)*) +(*TODO*) +let ldch (state : Processor.state) (operand : int) : unit = + state.regs.a <- operand + +(* LDX: X <- (m..m+2) *) +let ldx (state : Processor.state) (operand : int) : unit = + state.regs.x <- operand + +(* LDL: L <- (m..m+2) *) +let ldl (state : Processor.state) (operand : int) : unit = + state.regs.l <- operand + +(* LDS: S <- (m..m+2) *) +let lds (state : Processor.state) (operand : int) : unit = + state.regs.s <- operand + +(* LDT: T <- (m..m+2) *) +let ldt (state : Processor.state) (operand : int) : unit = + state.regs.t <- operand + +(* LDF: F <- (m..m+5) *) +(*TODO*) +let ldf (state : Processor.state) (operand : float) : unit = + state.regs.f <- operand + +(*m..m+2 <- (A)*) +let sta (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + Processor.writeMemAddr state operand valA + +(* m..m+2 <- (B) *) +let stb (state : Processor.state) (operand : int) : unit = + let valB = state.regs.b in + Processor.writeMemAddr state operand valB + +(* m..m+2 <- (X) *) +let stx (state : Processor.state) (operand : int) : unit = + let valX = state.regs.x in + Processor.writeMemAddr state operand valX + +(* m..m+2 <- (L) *) +let stl (state : Processor.state) (operand : int) : unit = + let valL = state.regs.l in + Processor.writeMemAddr state operand valL + +(* m..m+2 <- (S) *) +let sts (state : Processor.state) (operand : int) : unit = + let valS = state.regs.s in + Processor.writeMemAddr state operand valS + +(* m..m+2 <- (SW) *) +let stsw (state : Processor.state) (operand : int) : unit = + let valSW = state.regs.s in + Processor.writeMemAddr state operand valSW + +(* m..m+2 <- T register *) +let stt (state : Processor.state) (operand : int) : unit = + let valT = state.regs.t in + Processor.writeMemAddr state operand valT + +(* m..m+5 <- (F)*) +(*TODO change*) +let stf (state : Processor.state) (operand : int) : unit = + let valF = state.regs.f in + Processor.writeMemAddr state operand (int_of_float valF) + +(*X <- (X) + 1; (X):(m..m+2)*) +let tix (state : Processor.state) (operand : int) : unit = + state.regs.x <- state.regs.x + 1; + let valX = state.regs.x in + state.regs.sw <- (if valX < operand then 0 else if valX = operand then 1 else 2) \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml b/ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml new file mode 100644 index 0000000..ef18827 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/izvajalnikF4.ml @@ -0,0 +1,155 @@ +(*A <- (A)+ (m..m+2)*) +let add (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA + operand + +(*F (F) + (m..m+5)*) +(*TODO check!*) +let addf (state : Processor.state) (operand : int) : unit = + let valF = state.regs.f in + state.regs.f <- valF +. (float_of_int operand) + +(*A <- (A) & (m..m+2)*) +let andF (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA land operand + +(*(A):(m..m+2)*) +let comp (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.sw <- (if valA < operand then 0 else if valA = operand then 1 else 2) + +(*A <- (A) / (m..m+2)*) +let div (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA / operand + +(*A <- (A) * (m..m+2)*) +let mul (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA * operand + +(*A <- (A) | (m..m+2)*) +let orF (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA lor operand + +(*A <- (A) - (m..m+2)*) +let sub (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + state.regs.a <- valA - operand + +(*PC <- m*) +let j (state : Processor.state) (operand : int) : unit = + state.regs.pc <- operand + +(*PC <- m if CC set to =*) +let jeq (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 1 -> state.regs.pc <- operand + | _ -> () + +(*PC <- m if CC set to >*) +let jgt (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 2 -> state.regs.pc <- operand + | _ -> () + +(*PC <- m if CC set to <*) +let jlt (state : Processor.state) (operand : int) : unit = + let cc = state.regs.sw in + match cc with + | 0 -> state.regs.pc <- operand + | _ -> () + +(*L <- (PC); PC <- m*) +let jsub (state : Processor.state) (operand : int) : unit = + state.regs.l <- state.regs.pc; + state.regs.pc <- operand + +(*PC <- (L)*) +let rsub (state : Processor.state) : unit = + state.regs.pc <- state.regs.l + +(*A <- (m..m+2)*) +let lda (state : Processor.state) (operand : int) : unit = + state.regs.a <- operand + +(* LDB: B <- (m..m+2) *) +let ldb (state : Processor.state) (operand : int) : unit = + state.regs.b <- operand + +(*A [rightmost byte] ← (m)*) +(*TODO*) +let ldch (state : Processor.state) (operand : int) : unit = + state.regs.a <- operand + +(* LDX: X <- (m..m+2) *) +let ldx (state : Processor.state) (operand : int) : unit = + state.regs.x <- operand + +(* LDL: L <- (m..m+2) *) +let ldl (state : Processor.state) (operand : int) : unit = + state.regs.l <- operand + +(* LDS: S <- (m..m+2) *) +let lds (state : Processor.state) (operand : int) : unit = + state.regs.s <- operand + +(* LDT: T <- (m..m+2) *) +let ldt (state : Processor.state) (operand : int) : unit = + state.regs.t <- operand + +(* LDF: F <- (m..m+5) *) +(*TODO*) +let ldf (state : Processor.state) (operand : float) : unit = + state.regs.f <- operand + +(*m..m+2 <- (A)*) +let sta (state : Processor.state) (operand : int) : unit = + let valA = state.regs.a in + Processor.writeMemAddr state operand valA + +(* m..m+2 <- (B) *) +let stb (state : Processor.state) (operand : int) : unit = + let valB = state.regs.b in + Processor.writeMemAddr state operand valB + +(* m..m+2 <- (X) *) +let stx (state : Processor.state) (operand : int) : unit = + let valX = state.regs.x in + Processor.writeMemAddr state operand valX + +(* m..m+2 <- (L) *) +let stl (state : Processor.state) (operand : int) : unit = + let valL = state.regs.l in + Processor.writeMemAddr state operand valL + +(* m..m+2 <- (S) *) +let sts (state : Processor.state) (operand : int) : unit = + let valS = state.regs.s in + Processor.writeMemAddr state operand valS + +(* m..m+2 <- (SW) *) +let stsw (state : Processor.state) (operand : int) : unit = + let valSW = state.regs.s in + Processor.writeMemAddr state operand valSW + +(* m..m+2 <- T register *) +let stt (state : Processor.state) (operand : int) : unit = + let valT = state.regs.t in + Processor.writeMemAddr state operand valT + +(* m..m+5 <- (F)*) +(*TODO change*) +let stf (state : Processor.state) (operand : int) : unit = + let valF = state.regs.f in + Processor.writeMemAddr state operand (int_of_float valF) + +(*X <- (X) + 1; (X):(m..m+2)*) +let tix (state : Processor.state) (operand : int) : unit = + state.regs.x <- state.regs.x + 1; + let valX = state.regs.x in + state.regs.sw <- (if valX < operand then 0 else if valX = operand then 1 else 2) \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/lib/opcodeTable.ml b/ass2/SICocaml/sicxeDune/lib/opcodeTable.ml new file mode 100644 index 0000000..03dc20e --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/opcodeTable.ml @@ -0,0 +1,163 @@ +(*opcode hash table, formati ukazov in mnemoniki*) +type mnemonic = + (* Format 1 *) + | FIX | FLOAT | HIO | NORM | SIO | TIO + + (* Format 2 *) + | ADDR | CLEAR | COMPR | DIVR | MULR | RMO + | SHIFTL | SHIFTR | SUBR | SVC | TIXR + + (* Format 3/4 *) + | ADD | ADDF | AND | COMP | COMPF | DIV + | J | JEQ | JGT | JLT | JSUB | LDA | LDB | LDCH | LDF + | LDL | LDS | LDT | LDX | LPS | MUL | OR | RD + | RSUB | STA | STB | STCH | STF | STL | STS | STSW + | STT | STX | SUB | SUBF | TD | TIX | WD + +type format = + | F1 + | F2 + | F3_4 + +type info = { + mnemonic : mnemonic; + format : format; +} + +(* Opcode table *) + +let table : (int, info) Hashtbl.t = Hashtbl.create 128 + +let () = + let add op mnemonic format = + Hashtbl.add table op { mnemonic; format } + in + + (*Format 1 Instructions*) + add 0xC4 FIX F1; + add 0xC0 FLOAT F1; + add 0xC8 HIO F1; + add 0xC1 NORM F1; + add 0xF0 SIO F1; + add 0xF8 TIO F1; + + (*Format 2 Instructions*) + add 0x90 ADDR F2; + add 0xB4 CLEAR F2; + add 0xA0 COMPR F2; + add 0x9C DIVR F2; + add 0x98 MULR F2; + add 0xAC RMO F2; + add 0xA4 SHIFTL F2; + add 0xA8 SHIFTR F2; + add 0x94 SUBR F2; + add 0xB0 SVC F2; + add 0xB8 TIXR F2; + + (*Format 3/4 Instructions*) + add 0x18 ADD F3_4; + add 0x58 ADDF F3_4; + add 0x40 AND F3_4; + add 0x28 COMP F3_4; + add 0x88 COMPF F3_4; + add 0x24 DIV F3_4; + add 0x3C J F3_4; + add 0x30 JEQ F3_4; + add 0x34 JGT F3_4; + add 0x38 JLT F3_4; + add 0x48 JSUB F3_4; + add 0x00 LDA F3_4; + add 0x68 LDB F3_4; + add 0x50 LDCH F3_4; + add 0x70 LDF F3_4; + add 0x08 LDL F3_4; + add 0x6C LDS F3_4; + add 0x74 LDT F3_4; + add 0x04 LDX F3_4; + add 0xD0 LPS F3_4; + add 0x20 MUL F3_4; + add 0x44 OR F3_4; + add 0xD8 RD F3_4; + add 0x4C RSUB F3_4; + add 0x0C STA F3_4; + add 0x78 STB F3_4; + add 0x54 STCH F3_4; + add 0x80 STF F3_4; + add 0x14 STL F3_4; + add 0x7C STS F3_4; + add 0xE8 STSW F3_4; + add 0x84 STT F3_4; + add 0x10 STX F3_4; + add 0x1C SUB F3_4; + add 0x5C SUBF F3_4; + add 0xE0 TD F3_4; + add 0x2C TIX F3_4; + add 0xDC WD F3_4; +() + +(*mnemonic to string*) +let string_of_mnemonic = function + (* Format 1 *) + | FIX -> "FIX" + | FLOAT -> "FLOAT" + | HIO -> "HIO" + | NORM -> "NORM" + | SIO -> "SIO" + | TIO -> "TIO" + + (* Format 2 *) + | ADDR -> "ADDR" + | CLEAR -> "CLEAR" + | COMPR -> "COMPR" + | DIVR -> "DIVR" + | MULR -> "MULR" + | RMO -> "RMO" + | SHIFTL -> "SHIFTL" + | SHIFTR -> "SHIFTR" + | SUBR -> "SUBR" + | SVC -> "SVC" + | TIXR -> "TIXR" + + (* Format 3/4 *) + | ADD -> "ADD" + | ADDF -> "ADDF" + | AND -> "AND" + | COMP -> "COMP" + | COMPF -> "COMPF" + | DIV -> "DIV" + | J -> "J" + | JEQ -> "JEQ" + | JGT -> "JGT" + | JLT -> "JLT" + | JSUB -> "JSUB" + | LDA -> "LDA" + | LDB -> "LDB" + | LDCH -> "LDCH" + | LDF -> "LDF" + | LDL -> "LDL" + | LDS -> "LDS" + | LDT -> "LDT" + | LDX -> "LDX" + | LPS -> "LPS" + | MUL -> "MUL" + | OR -> "OR" + | RD -> "RD" + | RSUB -> "RSUB" + | STA -> "STA" + | STB -> "STB" + | STCH -> "STCH" + | STF -> "STF" + | STL -> "STL" + | STS -> "STS" + | STSW -> "STSW" + | STT -> "STT" + | STX -> "STX" + | SUB -> "SUB" + | SUBF -> "SUBF" + | TD -> "TD" + | TIX -> "TIX" + | WD -> "WD" + + +let format_str format = match format with + | F1 -> "F1" | F2 -> "F2" | F3_4 -> "F3/4" \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/lib/processor.ml b/ass2/SICocaml/sicxeDune/lib/processor.ml new file mode 100644 index 0000000..2499448 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/lib/processor.ml @@ -0,0 +1,111 @@ +type registers = { + mutable a : int; + mutable x : int; + mutable l : int; + mutable b : int; + mutable s : int; + mutable t : int; + mutable f : float; + mutable pc : int; + mutable sw : int +} +(*tip state predstavlja stanje SIC/XE, z pomnilnikom in registri*) +type state = { + regs : registers; + memory : Bytes.t +} + +(*beri 1 byte in povisaj PC*) +let fetch (state : state) : char = + let byte = Bytes.get state.memory state.regs.pc in + state.regs.pc <- state.regs.pc + 1; + byte + + (*beri 1 byte za offset in ne povecaj PC*) +let readMem (state : state) (offset : int) : char = + Bytes.get state.memory (state.regs.pc + offset) + + +(*beri 3 byte iz address*) +let readMemAddr (state : state) (address : int) : int = + let byte1 = Char.code (Bytes.get state.memory address) in + let byte2 = Char.code (Bytes.get state.memory (address + 1)) in + let byte3 = Char.code (Bytes.get state.memory (address + 2)) in + let value = (byte1 lsl 16) lor (byte2 lsl 8) lor byte3 in + value + + +(*napiši 3 byte inta na address*) +let writeMemAddr (state : state) (address : int) (value : int) : unit = + (* Mask and shift each byte *) + let byte1 = Char.chr ((value lsr 16) land 0xFF) in + let byte2 = Char.chr ((value lsr 8) land 0xFF) in + let byte3 = Char.chr (value land 0xFF) in + + (* Write bytes into memory *) + Bytes.set state.memory address byte1; + Bytes.set state.memory (address+1) byte2; + Bytes.set state.memory (address+2) byte3 + +(*popoč za pisanje instrukcij*) +let write_instruction3 (state : state) (address : int) (byte1 : char) (byte2 : char) (byte3 : char) : unit = + Bytes.set state.memory address byte1; + Bytes.set state.memory (address+1) byte2; + Bytes.set state.memory (address+2) byte3 + +(*povečaj pc za i*) +let pcIncrement (state : state) (i : int) : unit = + state.regs.pc <- state.regs.pc + i; + () + +(*beri register glede na reg_code*) + +let read_register_int (state: state) (reg_code : int) : int = + match reg_code with + | 0 -> state.regs.a + | 1 -> state.regs.x + | 2 -> state.regs.l + | 3 -> state.regs.b + | 4 -> state.regs.s + | 5 -> state.regs.t + | 6 -> int_of_float state.regs.f + | 8 -> state.regs.pc + | 9 -> state.regs.sw + | _ -> failwith "Invalid register code" + +let write_register_int (state : state) (reg_code : int) (value : int) : unit= + match reg_code with + | 0 -> state.regs.a <- value + | 1 -> state.regs.x <- value + | 2 -> state.regs.l <- value + | 3 -> state.regs.b <- value + | 4 -> state.regs.s <- value + | 5 -> state.regs.t <- value + | 6 -> state.regs.f <- float_of_int value + | 8 -> state.regs.pc <- value + | 9 -> state.regs.sw <- value + | _ -> failwith "Invalid register code" + +let print_memory (state : state) (n : int) : unit = + let mem = state.memory in + let len = Bytes.length mem in + let limit = min n len in + Printf.printf "Memory dump (first %d bytes):\n" limit; + for i = 0 to limit - 1 do + let byte = Char.code (Bytes.get mem i) in + Printf.printf "%02X " byte; + if (i + 1) mod 16 = 0 then Printf.printf "\n"; + done; + Printf.printf "\n" + +let print_regs state : unit = + let regs = state.regs in + Printf.printf "A: %06X\n" regs.a; + Printf.printf "B: %06X\n" regs.b; + Printf.printf "X: %06X\n" regs.x; + Printf.printf "L: %06X\n" regs.l; + Printf.printf "S: %06X\n" regs.s; + Printf.printf "T: %06X\n" regs.t; + Printf.printf "PC: %06X\n" regs.pc; + Printf.printf "SW: %06X\n" regs.sw; + Printf.printf "\n" \ No newline at end of file diff --git a/ass2/SICocaml/sicxeDune/sicxeDune.opam b/ass2/SICocaml/sicxeDune/sicxeDune.opam new file mode 100644 index 0000000..a43bbcb --- /dev/null +++ b/ass2/SICocaml/sicxeDune/sicxeDune.opam @@ -0,0 +1,32 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "A short synopsis" +description: "A longer description" +maintainer: ["Maintainer Name "] +authors: ["Author Name "] +license: "LICENSE" +tags: ["add topics" "to describe" "your" "project"] +homepage: "https://github.com/username/reponame" +doc: "https://url/to/documentation" +bug-reports: "https://github.com/username/reponame/issues" +depends: [ + "dune" {>= "3.20"} + "ocaml" + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/username/reponame.git" +x-maintenance-intent: ["(latest)"] diff --git a/ass2/SICocaml/sicxeDune/test/dune b/ass2/SICocaml/sicxeDune/test/dune new file mode 100644 index 0000000..e868230 --- /dev/null +++ b/ass2/SICocaml/sicxeDune/test/dune @@ -0,0 +1,2 @@ +(test + (name test_sicxeDune)) diff --git a/ass2/SICocaml/sicxeDune/test/test_sicxeDune.ml b/ass2/SICocaml/sicxeDune/test/test_sicxeDune.ml new file mode 100644 index 0000000..e69de29 diff --git a/ass2/SICocaml/test.ml b/ass2/SICocaml/test.ml index bec4bd9..d6cea4d 100644 --- a/ass2/SICocaml/test.ml +++ b/ass2/SICocaml/test.ml @@ -14,7 +14,7 @@ let test_execute () = let mem_size = 1024 in let memory = Bytes.make mem_size '\000' in let regs = { - a = 4; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0; + a = 0; b = 0; x = 0; l = 0; s = 0; t = 0; f = 0.0; pc = 0; sw = 0 } in let state = { memory; regs } in