CodeGolf: emulare parzialmente la vecchia CPU 8086

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Rieccomi dopo un pò di tempo! Qualcuno appassionato di golf? :)


450px-Golfer_swing.jpg

Anche questa volta voglio proporre qualcosa, e no, non si tratta di una partita a golf. :lol:



Scherzi a parte, qualche tempo fa ho notato questo CodeGolf che ho provveduto a salvare tra i segnalibri: https://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu

Riporto schematicamente ciò che dovrà essere implementato; link utili, il binario da eseguire, e il codice sorgente, li trovate al link qui sopra.

  • Only the following opcodes need to be implemented:
    • mov, push, pop, xchg
    • add, adc, sub, sbb, cmp, and, or, xor
    • inc, dec
    • call, ret, jmp
    • jb, jz, jbe, js, jnb, jnz, jnbe, jns
    • stc, clc
    • hlt, nop
  • As a result of this, you only need to calculate the carry, zero and sign flags
  • Don't implement segments. Assume cs = ds = ss = 0.
  • No prefixes
  • No kinds of interrupts or port IO
  • No string functions
  • No two-byte opcodes (0F..)
  • No floating point arithmetic
  • (obviously) no 32-bit things, sse, mmx, ... whatever has not yet been invented in 1979
  • You do not have to count cycles or do any timing

Start with ip = 0 and sp = 100h.

Input: Your emulator should take a binary program in any kind of format you like as input (read from file, predefined array, ...) and load it into memory at address 0.

Output: The video RAM starts at address 8000h, every byte is one (ASCII-)character. Emulate a 80x25 screen to console. Treat zero bytes like spaces.

Spero di vedere qualche partecipante o almeno qualche domanda, considerando che è un contest a parer mio interessante/stimolante. :D

Aspetterò qualche soluzione o qualche giorno prima di linkare la mia; lascio solo lo screen del mio output sotto spoiler:
68747470733a2f2f692e6962622e636f2f38385a32634d4b2f636f6465676f6c662e706e67
 

rctimelines

Utente Èlite
5,144
2,023
CPU
Ryzen 7 2700X | i7-6700k@4.5 | i5-4460... altri
Dissipatore
wraith MAX | Scythe Katana2|Arctic Freezer 11LP
Scheda Madre
Asrock B450 Fatal1ty 4K | Asus Prime Z270P | Acer Veriton
HDD
Samsung 970evo m.2 | vari | Samsung 860 evo
RAM
16GB G.Skill TridentZ 3000 | 16GB CORSAIR 2133 | 8GB DDR3 1600
GPU
RadeonPro WX3100 4G | ZOTAC GTX 1070 8G | Quadro k620 2G
Monitor
DELL 2419P 2K + Benq 17" | LG Ultrawide 27''
Net
fibra 1000
OS
Windows10-pro64/OpenSUSE-QL15.1/Debian 10.3
Si può scrivere in qualsiasi linguaggio?

Inviato dal mio Nexus 5X utilizzando Tapatalk
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed

Andretti60

Utente Èlite
6,440
5,091
Roba che facevo quaranta anni fa, da buon hacker, quando passavo le notti nei laboratori del dipartimento di fisica invece che preparare gli ultimi esami. Ovviamente tutto in standard C. Vedo comunque che lo spirito rimane nella comunità, vedere fare queste cose in JS e Python è impressionante. Beh, in fondo non è così difficile, solo tedioso. Io scrissi un intero emulatore per una calcolatrice HP programmabile, non ricordo il modello. Chi me lo fece fare... Quello più divertente fu emulatore BASIC... con variabili a un numero infinito di cifre decimali... pazzo...
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Roba che facevo quaranta anni fa, da buon hacker, quando passavo le notti nei laboratori del dipartimento di fisica invece che preparare gli ultimi esami. Ovviamente tutto in standard C. Vedo comunque che lo spirito rimane nella comunità, vedere fare queste cose in JS e Python è impressionante. Beh, in fondo non è così difficile, solo tedioso. Io scrissi un intero emulatore per una calcolatrice HP programmabile, non ricordo il modello. Chi me lo fece fare... Quello più divertente fu emulatore BASIC... con variabili a un numero infinito di cifre decimali... pazzo...

Richiede principalmente tempo per andare a guardarsi le documentazioni. Nel caso di specie è quasi sufficiente guardare solo l'elenco di opcodes e la struttura delle istruzioni. Non dovendo gestire segmenti e altro, come la memoria video (magari supportare VGA etc), non è particolarmente complesso, ma dipende poi da quanto si programma (secondo me).
 
  • Mi piace
Reazioni: Andretti60

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Inizio a pubblicare il mio: https://github.com/DispatchCode/NaTE

Brevemente, ild.c è il progetto che sto piano piano portando avanti; si tratta in questo caso di una versione molto semplificata e adattata al 16bit. Di fatto si occupa di disassemblare l'istruzione scomponendola nelle sue parti.

cpu.c inizializza la CPU, creando anche la "ram" e inizializzando i registri.

cpu_exec.c esegue una singola istruzione disassemblata in precedenza, ed è di fatto l'emulazione vera e propria.

Questo due ultimi file sono parte di un progetto datato che ho messo in standby, per così dire, e molto più vasto.
 
  • Mi piace
Reazioni: Andretti60

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Mi permetto di riesumare un vecchio topic perchè ho un aggiornamento.

Siccome sto iniziando a studiare un pò Rust nel tempo libero, ho pensato di scriverlo anche in Rust. Se qualcuno fosse interessato qui trova il codice: https://github.com/DispatchCode/NaTE-rust :)

Sotto spoiler metto uno screenshot:

rust_nate.png

Mi manca un pò la libertà che lascia il C... ma allo stesso tempo trovo Rust interessante, quindi proseguirò ad utilizzarlo sicuramente! :)
 
  • Mi piace
Reazioni: Mursey

pabloski

Utente Èlite
2,868
916
Siccome sto iniziando a studiare un pò Rust nel tempo libero

Hihihi ormai sei stato risucchiato dal lato oscuro :D

Mi manca un pò la libertà che lascia il C... ma allo stesso tempo trovo Rust interessante, quindi proseguirò ad utilizzarlo sicuramente! :)

La libertà di sviluppare usando vagonate di anti-pattern! A me fanno incazzare quelli che vanno su reddit o stackoverflow e sparano a zero contro Rust. Specialmente i programmatori C++. Evidentemente si sentono detronizzati o non riescono ad adeguarsi alle rigide regole del modello di memoria di Rust....e s'incazzano!

Ma in tutta onestà, ho trovato Rust una boccata d'aria fresca in un mondo ormai stagnante. Le difficoltà dovute al dover acquisire nuove abitudini di programmazione, te le ritrovi ripagate per mille.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Hihihi ormai sei stato risucchiato dal lato oscuro :D

Ho paura di si... :D

La libertà di sviluppare usando vagonate di anti-pattern! A me fanno incazzare quelli che vanno su reddit o stackoverflow e sparano a zero contro Rust. Specialmente i programmatori C++. Evidentemente si sentono detronizzati o non riescono ad adeguarsi alle rigide regole del modello di memoria di Rust....e s'incazzano!

Ciò che mi ha creato qualche "difficoltà" è stata appunto la rigidità nel compiere alcune operazioni.
Faccio un esempio:

C:
memcpy(&instr->disp, (data + index), instr->disp_len);

Qui ho data che è un puntatore a char e instr->disp che è un uint16. Io sono certo che quel "len" valga 1 o 2, quindi copio 1-2 byte dalla locazione puntata da data+index in disp.

In Rust, non conoscendolo ancora decentemente, ho dovuto ripiegare su:

Codice:
fn read_val(data : &Vec<u8>, index : usize, val_size : usize) -> u16{
    match val_size {
        1 => { data[index] as u16 },
        2 => { ((data[index + 1] as u16) << 8) | (data[index]) as u16},
        _ => { 0 }
    }
}

Altra situazione? La somma tra due u8/u16 che va in overflow, piuttosto che su, ad esempio, u8 e u16... che non si può fare avendo tipo differente. :D
Utilizzando C (ma anche tanti altri linguaggi, in realtà) puoi fare di tutto.

Comunque sto apprezzando altri aspetti di Rust; se devo trovare ciò che secondo me è ancora un punto critico, sono le documentazioni di alcuni (o molti) crate. Lo sto utilizzando anche per un altro "programmino" dove ho iniziato ad usare una GUI, ed ho avute non poche difficoltà inizialmente (e ora che tornerò a metterci mano immagino proseguiranno).

Ma in tutta onestà, ho trovato Rust una boccata d'aria fresca in un mondo ormai stagnante. Le difficoltà dovute al dover acquisire nuove abitudini di programmazione, te le ritrovi ripagate per mille.

Su questo concordo.
Inoltre ci si trova a dover pensare in un modo un pò diverso rispetto all'approccio che si ha con altri linguaggi (e paradigmi).
 

pabloski

Utente Èlite
2,868
916
C:
memcpy(&instr->disp, (data + index), instr->disp_len);

Beh però questo è l'equivalente di un triplo salto mortale :D

Il compilatore non avrebbe mai modo di capire che sta succedendo e cosa potrebbe andare storto. E Rust è pensato proprio per evitare questa confusione. Alla fin fine si tratta di dare al compilatore le informazioni necessarie per capire la possibile evoluzione dello stato del programma. Il compilatore vuole sapere, in ogni istante, qual è il dominio di ognuna delle variabili. E si spinge fino al punto, in casi particolari dove non riesce a capirlo da solo, a farti specificare pure il lifetime di una variabile.


dove ho iniziato ad usare una GUI

Azul?
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,208
1,845
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Beh però questo è l'equivalente di un triplo salto mortale :D

Il compilatore non avrebbe mai modo di capire che sta succedendo e cosa potrebbe andare storto. E Rust è pensato proprio per evitare questa confusione. Alla fin fine si tratta di dare al compilatore le informazioni necessarie per capire la possibile evoluzione dello stato del programma. Il compilatore vuole sapere, in ogni istante, qual è il dominio di ognuna delle variabili. E si spinge fino al punto, in casi particolari dove non riesce a capirlo da solo, a farti specificare pure il lifetime di una variabile.

Si, è un triplo salto mortale... ma è comodo :D
Non sono un male tutti i check che vengono fatti, alcuni sono un pò "rognosi" se non si è abituati, ma alla fine credo che i benefici si vedano poi in progetti più corposi dove tutte le situazioni "ambigue" sono causa di bug, magari a causa di un particolare evento o disattenzioni di chi sviluppa.

Tu hai studiato/studi Rust per puro interesse o lo utilizzi per lavoro?


No, quello l'ho visto e per applicazioni che fanno uso di grafica credo proprio che lo proverò.
Voglio disegnare su una finestra un'immagine - che genero - e su consiglio ho scelto ImGui. A questo ho abbinato poi glium e gfx.
 

pabloski

Utente Èlite
2,868
916
Tu hai studiato/studi Rust per puro interesse o lo utilizzi per lavoro?

Eh magari. In Italia siamo fermi a C# e VB.NET :asd: ...un giorno forse ci faranno lavorare su Go...entro il 2080 qualche progetto sarà realizzato in Rust :D


No, quello l'ho visto e per applicazioni che fanno uso di grafica credo proprio che lo proverò.
Voglio disegnare su una finestra un'immagine - che genero - e su consiglio ho scelto ImGui. A questo ho abbinato poi glium e gfx.

Ottima scelta ImGui. Che tra l'altro è la libreria a cui si sono ispirati i creatori di Azul, che però hanno deciso di utilizzare il WebRender di Mozilla, piuttosto che impelagarsi nei meandri delle API Windows, Linux e compagnia.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili