DIY करते हैं, यह खुद गेम कंसोल है

छवि


यह पोस्ट मेरी परियोजना "होममेड" कंसोल वीडियो कंसोल से बना एक परिचय है। मैं रेट्रो कंसोल और आधुनिक नमूनों दोनों से प्रेरित था, लेकिन मुझे अपनी खुद की वास्तुकला मिली। मेरे दोस्तों ने लगातार मुझसे कहा कि मुझे अपने प्रोजेक्ट के बारे में बात करनी चाहिए, न कि सब कुछ "खुद के लिए" विशेष रूप से करना चाहिए, इसलिए यहां मैं इस पोस्ट को प्रकाशित कर रहा हूं।


ध्यान दें, यह एक अनुवाद है


यह सब कैसे शुरू हुआ


मेरा नाम सर्जियो विएरा है, मैं 80 और 90 के दशक में पुर्तगाल में बड़ा हुआ, मेरे पास रेट्रो गेमिंग के लिए एक लंबी उदासीनता है, खासकर तीसरी और चौथी पीढ़ी के कंसोल के लिए।


कुछ साल पहले, मैंने इलेक्ट्रॉनिक्स को बेहतर ढंग से समझने और अपना उपसर्ग बनाने का प्रयास करने का फैसला किया।


पेशे से, मैं एक प्रोग्रामर हूं और इलेक्ट्रॉनिक इंजीनियर के रूप में कोई अनुभव नहीं था, इसके अलावा (और इस पर विचार नहीं किया जाना चाहिए) मेरे डेस्टकॉप का स्वतंत्र उन्नयन।


हालाँकि मेरे पास कोई अनुभव नहीं है, मैंने खुद से कहा "क्यों नहीं?", मैंने कई किताबें, कई इलेक्ट्रॉनिक किट खरीदे और जो अध्ययन करने लायक था उसके बारे में मेरी भावनाओं के आधार पर अध्ययन करना शुरू किया।


मैं उन लोगों के समान एक उपसर्ग बनाना चाहता था जो मुझे उदासीन बनाते हैं, मैं एनईएस और सुपर निंटेंडो के बीच कुछ चाहता था, या शायद सेगा मास्टर सिस्टम और मेगा ड्राइव के बीच


इन कंसोलों में एक सीपीयू, एक मूल वीडियो चिप (उन्हें तब GPU नहीं कहा जाता था) और एक ऑडियो चिप, कभी-कभी अंतर्निहित और कभी-कभी बाहरी होता है।


खेलों को कारतूस पर वितरित किया गया था, जो सामान्य रूप से लोहे के विस्तार थे, कभी-कभी केवल रॉम चिप्स, और कभी-कभी अतिरिक्त घटक होते थे।


मूल योजना निम्नलिखित विशेषताओं के साथ एक उपसर्ग बनाने की थी:


  • अनुकरण के बिना, गेम और कार्यक्रमों को वास्तविक हार्डवेयर पर काम करना चाहिए, जरूरी नहीं कि उन समयों में से एक ही हो, लेकिन कार्य के लिए पर्याप्त तेजी से, और कुछ भी नहीं।
  • असली रेट्रो सीपीयू के साथ।
  • एनालॉग टीवी आउटपुट के साथ।
  • ध्वनि के साथ
  • दोहरी नियंत्रक समर्थन के साथ
  • स्क्रॉलिंग बीक्स और एनीमेशन स्प्राइट्स
  • मारियो जैसे प्लेटफ़ॉर्म गेम का समर्थन करने की सुविधाओं के साथ, और निश्चित रूप से अन्य खेलों के सभी प्रकार।
  • एसडी कार्ड से गेम और प्रोग्राम डाउनलोड करने के साथ।

एसडी कार्ड, और कारतूस क्यों नहीं, ठीक है, मूल रूप से यह सिर्फ इतना अधिक व्यावहारिक है, आप उन्हें अपने कंप्यूटर से कॉपी कर सकते हैं। और कारतूस का मतलब होगा, सबसे पहले, सेट-टॉप बॉक्स में अधिक लोहा और दूसरा, प्रत्येक कार्यक्रम के लिए लोहे का उत्पादन करना।


उत्पादन


वीडियो संकेत


मैंने जो सबसे पहला काम किया, वह था वीडियो सिग्नल।


उस अवधि के किसी भी कंसोल को जो मैंने नमूने के रूप में लिया था, उसमें विभिन्न मालिकाना ग्राफिक्स वाले चिप्स थे, जिसका अर्थ है कि उन सभी के अलग-अलग विनिर्देश थे।
इस कारण से, मैं तैयार ग्राफिक्स चिप का उपयोग नहीं करना चाहता था, मैं चाहता था कि मेरे कंसोल में अद्वितीय ग्राफिक्स विनिर्देश हों। और जब से मैं अपनी खुद की ग्राफिक चिप नहीं बना सका, और उस समय मैं अभी भी FPGA का उपयोग नहीं कर सकता था, मैंने खुद को 8-बिट, 20 मेगाहर्ट्ज़ माइक्रोकंट्रोलर का उपयोग करके ग्राफिक सिग्नल की सॉफ़्टवेयर-जनरेटेड पीढ़ी तक सीमित करने का निर्णय लिया।


यह बहुत ज्यादा नहीं है, और उस स्तर के ग्राफिक्स के लिए सिर्फ एक शक्तिशाली पर्याप्त समाधान है जिसमें मुझे दिलचस्पी थी।


और इसलिए, मैंने टीवी के लिए एक PAL वीडियो सिग्नल उत्पन्न करने के लिए 20 MHz की शुद्धता पर Atmega644 माइक्रोकंट्रोलर का उपयोग करना शुरू कर दिया। मुझे बिट- पीएएल प्रोटोकॉल को हरा देना पड़ा क्योंकि चिप खुद नहीं जानता कि यह कैसे करना है।


imageVPU Test 1


imageVPU टेस्ट 2


माइक्रोकंट्रोलर एक 8-बिट रंग (RGB332, 3 बिट्स रेड, 3 बिट्स ग्रीन और 2 ब्लू) का उत्पादन करता है और निष्क्रिय DAC इसे RGB में परिवर्तित करता है। सौभाग्य से, पुर्तगाल में, लगभग सभी टीवी एक SCART कनेक्टर से लैस हैं और वे RGB इनपुट का समर्थन करते हैं।


सही ग्राफिक्स सबसिस्टम


चूंकि माइक्रोकंट्रोलर काफी शक्तिशाली है, और मैंने इसे विशेष रूप से एक वीडियो सिग्नल बनाने के लिए उपयोग करने का फैसला किया (मैंने इसे वीपीयू - वीडियो प्रोसेसिंग यूनिट कहा है), फिर मैंने उसी समय एक डबल बफर को व्यवस्थित करने का फैसला किया।


यह पता चला कि दूसरी माइक्रोकंट्रोलर (पीपीयू, पिक्चर प्रोसेसिंग यूनिट, एटमेगा 1284 चिप भी 20 मेगाहर्ट्ज में) ने रैम चिप 1 (मैंने इसे वीआरएएम 1 कहा था) में एक तस्वीर तैयार की, और पहले वाले ने उसी समय टीवी को दूसरी चिप (वीआरएएम 2) की सामग्री भेजी।


एक फ्रेम के बाद, और PAL सिस्टम में दो फ्रेम एक सेकंड का 1/25 है, VPU VRAMs को स्विच करता है और उन्हें स्वैप किया जाता है, PPU VRAM2 में एक तस्वीर बनाता है, और VPU टीवी आउटपुट के लिए VRAM1 को डंप करता है।


वीडियो कार्ड बहुत जटिल हो गया क्योंकि मुझे बाहरी हार्डवेयर का उपयोग करना पड़ा ताकि दोनों माइक्रोकंट्रोलर मेमोरी मॉड्यूल का उपयोग कर सकें और रैम तक पहुंच को तेज कर सकें, क्योंकि इसमें बिट-बैंगिंग भी है, इसलिए मुझे काउंटर, लाइन चयनकर्ता, ट्रांससीवर्स, आदि के रूप में 74 श्रृंखला चिप्स जोड़ना पड़ा। ।


वीपीयू और पीपीयू के लिए फर्मवेयर भी बोझिल हो गए क्योंकि मुझे ग्राफिक्स से अधिकतम गति प्राप्त करने के लिए बहुत सारे कोड लिखने पड़े। पहले सब कुछ कोडांतरक में लिखा गया था, फिर सी में फिर से लिखा गया था।


imageVideo बोर्ड 1


imageVideo बोर्ड 2


परिणामस्वरूप, PPU एक 224x192 पिक्सेल चित्र बनाता है, जिसे तब VPU के माध्यम से टीवी पर भेजा जाता है। आपको रिज़ॉल्यूशन कम मिल सकता है, लेकिन वास्तव में यह लगभग उतना ही है जितना उस समय का कंसोल वास्तव में 256x224 था। थोड़ा कम रिज़ॉल्यूशन, लेकिन मुझे अधिक सुविधाओं को जोड़ने की अनुमति दी गई है जो सिस्टम एक फ्रेम में गणना करने का प्रबंधन करता है।


पुराने दिनों की तरह, PPU के अपने स्वयं के कठोर मैकेनिक हैं, जिन्हें आप उपयोग करने में सक्षम होना चाहिए। बैकिंग (बैकिंग) को 8x8 पिक्सेल वर्णों से प्रस्तुत किया जाता है, जिसे टाइल भी कहा जाता है। यह पता चला है कि पृष्ठभूमि का आकार 28x24 टाइल है।


ताकि बैकिंग सुचारू रूप से स्क्रॉल कर सके, पिक्सेल द्वारा पिक्सेल, मैंने ऐसा किया 4 वर्चुअल स्क्रीन हैं, प्रत्येक 28x24 टाइलें जो क्रमिक रूप से मेमोरी में जाती हैं और एक दूसरे के चारों ओर लपेटी जाती हैं, तस्वीर में यह अधिक स्पष्ट है।


imageBackground


छविविशिष्ट पृष्ठभूमि


पृष्ठभूमि के शीर्ष पर, PPU 64 स्प्राइट्स प्रदान कर सकता है जो ऊंचाई या चौड़ाई में 8 या 16 पिक्सेल हो सकते हैं, अर्थात, 1, 2 या 4 टाइलें और क्षैतिज और / या लंबवत रूप से फ़्लिप किया जा सकता है।


पीठ के शीर्ष पर, आप आकार में एक बफर 28x6 टाइल के साथ एक ओवरले को भी प्रस्तुत कर सकते हैं, यह HUDs, स्कोर प्रदान करने के लिए था ताकि मुख्य स्प्राइट्स और पीठ की स्क्रॉलिंग में हस्तक्षेप न हो।


एक "उन्नत" विशेषता यह है कि बैकिंग को पूरी तरह से स्क्रॉल नहीं किया जा सकता है, लेकिन प्रत्येक पंक्ति को अलग-अलग किया जाता है, जो सभी प्रकार के दिलचस्प प्रभावों जैसे विभाजन स्क्रीन या निकट- लंबन की अनुमति देता है।


विशेषताओं की एक तालिका भी है जो आपको प्रत्येक टाइल को 0 से 3 के मान तक सेट करने की अनुमति देती है, और फिर आप एक विशेषता वाले सभी टाइलों के लिए टाइल्स का एक पृष्ठ निर्दिष्ट कर सकते हैं या उनका प्रतीकात्मक मूल्य बढ़ा सकते हैं। यह सुविधाजनक है जब बैक-अप के कुछ हिस्सों को नियमित रूप से बदलने की आवश्यकता होती है और सीपीयू को प्रत्येक टाइल को व्यक्तिगत रूप से गणना करने की आवश्यकता नहीं होती है, यह केवल कुछ कहने के लिए पर्याप्त है: "विशेषता 1 के साथ सभी टाइलें, 2 के साथ अपने चरित्र के संख्यात्मक मूल्य में वृद्धि, इसी तरह की चीजें अलग-अलग तकनीकों द्वारा लागू की जा सकती हैं। उदाहरण के लिए, मारियो में ब्लॉक टाइल में जहां प्रश्न चिह्न एनिमेटेड है या उन खेलों में जहां एक झरना है जिसमें सभी टाइलें लगातार गिरते पानी के प्रभाव को बदल रही हैं।


सीपीयू


जब मेरे वीडियो कार्ड ने काम किया, तो मैंने सीपीयू के साथ अपने सेट-टॉप बॉक्स के लिए ज़िलॉग 80 के रूप में काम करना शुरू कर दिया।


एक कारण है कि Z80 को क्यों चुना गया था, ठीक है, इस तथ्य के अलावा कि यह एक शांत रेट्रो सीपीयू है, दो 16-बिट रिक्त स्थान को संबोधित करने की क्षमता है, एक मेमोरी के लिए और दूसरा I / O पोर्ट के लिए, कोई कम पौराणिक 6502 नहीं है , उदाहरण के लिए, नहीं , यह केवल 16 बिट स्थान को संबोधित कर सकता है, और आपको इसे मेमोरी के साथ-साथ विभिन्न बाहरी उपकरणों, वीडियो, ऑडियो, जॉयस्टिक, हार्डवेयर यादृच्छिक संख्या जनरेटर, आदि में मैप करना होगा। दो एड्रेस स्पेस के लिए यह अधिक सुविधाजनक है, एक पूरी तरह से 64 किलोबाइट तक कोड और डेटा मेमोरी में और दूसरा बाहरी उपकरणों तक पहुंच के लिए।


सबसे पहले, मैंने CPU को EEPROM से जोड़ा, जिसमें मेरा परीक्षण कार्यक्रम स्थित था और मैंने इसे I / O स्थान के माध्यम से उस माइक्रोकंट्रोलर से भी जोड़ा था जिसे मैंने स्थापित किया था ताकि मैं अपने कंप्यूटर के साथ RS232 के माध्यम से संचार कर सकूं और यह देख सकूं कि CPU और बाकी सभी ने कैसे काम किया। मैं इस एटमेगा 324 माइक्रोकंट्रोलर को 20 मेगाहर्ट्ज IO MCU पर संचालित करता हूं - एक इनपुट / आउटपुट माइक्रोकंट्रोलर यूनिट, यह गेम कंट्रोलर्स (जॉयस्टिक), एसडी कार्ड रीडर, पीएस -2 कीबोर्ड और RS232 के माध्यम से एक कम्युनिकेटर तक पहुंच को नियंत्रित करने के लिए जिम्मेदार है।


imageCPU बोर्ड 1


सीपीयू एक 128 किलोबाइट मेमोरी चिप से जुड़ता है, जिसमें से केवल 56 किलोबाइट उपलब्ध हैं, यह निश्चित रूप से बकवास है, लेकिन मुझे केवल 128 या 32 किलोबाइट चिप्स मिल सकते हैं। यह पता चला है कि मेमोरी में 8 किलोबाइट्स ROM और 56 किलोबाइट्स RAM होते हैं।


उसके बाद, मैंने इस पुस्तकालय का उपयोग करके IO MCU फर्मवेयर को अपडेट किया और मुझे एसडी कार्ड पाठकों का समर्थन मिला।


अब सीपीयू निर्देशिकाओं के माध्यम से जा सकता है, देखें कि उनमें क्या निहित है, फाइलों को खोलें और पढ़ें। यह सब I / O स्पेस में विशिष्ट पतों पर लिखने और पढ़ने से होता है।


सीपीयू को पीपीयू से कनेक्ट करें


अगली चीज जो मैंने की है वह है सीपीयू और पीपीयू के बीच संबंध। ऐसा करने के लिए, मैंने एक "सरल समाधान" लागू किया जो कि दोहरे पोर्ट रैम को खरीदना था, यह ऐसी रैम चिप है जिसे सीधे दो अलग-अलग बसों से जोड़ा जा सकता है। यह उसे लाइन सिलेक्टर जैसे अतिरिक्त चिप्स से छुटकारा पाने की अनुमति देता है और इसके अलावा, दोनों चिप्स से मेमोरी तक लगभग एक साथ पहुंच की अनुमति देता है। एक अन्य पीपीयू सीधे अपने गैर-नकाबपोश व्यवधानों को सक्रिय करके प्रत्येक फ्रेम पर सीपीयू तक पहुंच सकता है। यह पता चला है कि सीपीयू प्रत्येक फ्रेम पर एक रुकावट प्राप्त करता है, जो कि विभिन्न समय के कार्यों के लिए और ग्राफिक्स अपडेट करने का समय होने पर समझने के लिए उपयोगी है।


सीपीयू, पीपीयू और वीपीयू का प्रत्येक इंटरैक्शन फ्रेम निम्नलिखित योजना के अनुसार होता है:


  1. PPU, PPU मेमोरी से आंतरिक मेमोरी की जानकारी को कॉपी करता है।
  2. PPU CPU को एक इंटरप्ट सिग्नल भेजता है।
  3. उसी समय:
    • CPU रुकावट फ़ंक्शन में कूदता है और एक नए ग्राफिक्स राज्य के साथ PPU मेमोरी को अपडेट करना शुरू करता है। अगले ब्लॉक तक कार्यक्रम को बीच में से लौटना चाहिए।
    • पीपीयू पहले वीआरएएम में से एक पर कॉपी की गई जानकारी के आधार पर एक चित्र प्रस्तुत करता है।
    • वीपीयू एक और वीआरएएम से टीवी आउटपुट पर एक तस्वीर भेजता है।

उसी समय के आसपास, मैंने गेम कंट्रोलर्स को सपोर्ट करना शुरू कर दिया, सबसे पहले मैं निनटेंडो कंट्रोलर्स का इस्तेमाल करना चाहता था, लेकिन उनकी सॉकेट्स मालिकाना हैं और आम तौर पर उन्हें ढूंढना मुश्किल है, इसलिए मैंने मेगा ड्राइव / जेनेसिस के साथ संगत 6-बटन कंट्रोलर्स पर समझौता किया, उनके पास मानक DB-9 सॉकेट्स हैं। जो हर जगह हैं।


imageJoint बोर्ड 1


पहला असली खेल लिखना


इस समय, मेरे पास पहले से ही एक सीपीयू था जो पीपीयू को नियंत्रित करने में सक्षम था, जॉयस्टिक के साथ काम कर रहा था, एसडी कार्ड पढ़ रहा था ... यह Z80 कोडांतरक में निश्चित रूप से पहला गेम लिखने का समय था, इसमें मुझे खाली समय से कई दिन लगे।



गतिशील ग्राफिक्स जोड़ें


सब कुछ सुपर था, मेरे पास अपना गेम कंसोल था, लेकिन यह मेरे लिए पर्याप्त नहीं था, क्योंकि खेल में मुझे पीपीयू मेमोरी में ग्राफिक्स सिलना का उपयोग करना था और एक विशिष्ट गेम के लिए टाइल खींचना असंभव था और इसे केवल रॉम को फिर से न बदलकर बदलना संभव था। मैं इस बारे में सोचने लगा कि अधिक मेमोरी कैसे जोड़ी जाए ताकि सीपीयू टाइल्स के लिए वर्णों को इसमें लोड कर सके, और फिर पीपीयू तब इसे वहां से पढ़ सकता है और इसे कैसे आसान कर सकता है क्योंकि उपसर्ग पहले से ही जटिल और बड़ा हो गया था।


और मैं निम्नलिखित के साथ आया था: केवल पीपीयू में इस नई मेमोरी तक पहुंच होगी, और सीपीयू पीपीयू के माध्यम से डेटा लोड करेगा और जबकि यह लोडिंग प्रक्रिया जारी है, इस मेमोरी का उपयोग ड्राइंग के लिए नहीं किया जा सकता है, लेकिन इस समय रोम से आकर्षित करना संभव होगा।


लोड के अंत के बाद, सीपीयू आंतरिक ROM मेमोरी को इस नई मेमोरी में स्विच कर देगा, जिसे मैंने कैरेक्टर रैम (CHR-RAM) कहा है और इस मोड में, PPU डायनामिक ग्राफिक्स ड्राइंग करना शुरू कर देगा, यह संभवतः सबसे अच्छा समाधान नहीं है, लेकिन यह काम करता है। नतीजतन, एक नई मेमोरी 128 किलोबाइट्स स्थापित की गई थी और पृष्ठभूमि के लिए प्रत्येक 8x8 पिक्सेल के 1024 वर्ण और स्प्राइट के लिए समान वर्ण संग्रहीत कर सकते हैं।


imageJoint बोर्ड 2


और अंत में ध्वनि


हाथ आखिरी आवाज तक पहुंचे। सबसे पहले, मुझे एक ऐसी ध्वनि चाहिए थी जो उज़ोबॉक्स में है, अर्थात, माइक्रोकंट्रोलर PWM ध्वनि के 4 चैनल उत्पन्न करता है।


हालांकि, यह पता चला कि मैं आसानी से विंटेज चिप्स प्राप्त कर सकता हूं और मैंने कई एफएम संश्लेषण चिप्स YM3438 का आदेश दिया, ये लोग मेगा ड्राइव / उत्पत्ति में उपयोग किए जाने वाले YM2612 के साथ पूरी तरह से संगत हैं। उन्हें स्थापित करके आप माइक्रोकंट्रोलर द्वारा उत्पादित गुणवत्ता वाले संगीत मेगा ड्राइव और ध्वनि प्रभाव प्राप्त कर सकते हैं।


मैंने एक और माइक्रोकंट्रोलर स्थापित किया और इसे एसपीयू (साउंड प्रोसेसर यूनिट) कहा, यह वाईएम 3438 को नियंत्रित करता है और खुद को आवाज पैदा कर सकता है। सीपीयू इसे एक दोहरे पोर्ट मेमोरी के माध्यम से नियंत्रित करता है, इस समय यह केवल 2 किलोबाइट है।


ग्राफिक यूनिट की तरह, साउंड यूनिट में पीसीएम सैंपल और साउंड पैच को स्टोर करने के लिए 128 किलोबाइट मेमोरी होती है, सीपीयू एसपीयू तक पहुंचकर इस मेमोरी में डेटा लोड करता है। यह पता चला कि CPU या तो SPU को इस मेमोरी से कमांड निष्पादित करने के लिए कहता है या SPU के लिए कमांड को हर फ्रेम में अपडेट करता है।


सीपीयू एसपीयू मेमोरी में चार परिपत्र बफ़र्स के माध्यम से चार पीडब्लूएम चैनलों को नियंत्रित करता है। एसपीयू इन बफ़र्स के माध्यम से जाता है और उन्हें लिखे गए आदेशों को निष्पादित करता है। एफएम संश्लेषण चिप के लिए एक ऐसा बफर भी है।


कुल मिलाकर, ग्राफ़ की तरह, सीपीयू और एसपीयू के बीच बातचीत योजना के अनुसार होती है:


  1. SPU आंतरिक मेमोरी से SPU के डेटा की प्रतिलिपि बनाता है।
  2. SPU PPU से एक रुकावट की प्रतीक्षा कर रहा है (यह सिंक्रनाइज़ेशन के लिए है)
  3. उसी समय
    • CPU PWM चैनल बफ़र और FM सिंथेसाइज़र बफ़र अद्यतन करता है।
    • एसपीयू आंतरिक मेमोरी में डेटा के अनुसार बफ़र्स में कमांड निष्पादित करता है।
    • इन सब के साथ, SPU 16 किलोहर्ट्ज़ की आवृत्ति पर PWM की आवाज़ को अपडेट करता है।

imageSound बोर्ड 1


आखिर में क्या निकला


सभी ब्लॉक तैयार होने के बाद, कुछ ब्रेडबोर्ड पर गए।
सीपीयू ब्लॉक के लिए, मैं एक कस्टम पीसीबी विकसित और ऑर्डर करने में सक्षम था, मुझे नहीं पता कि क्या यह अन्य मॉड्यूल के लिए इसके लायक है, मुझे लगता है कि मैं वास्तव में भाग्यशाली था कि मेरे पीसीबी ने तुरंत काम किया।


ब्रेडबोर्ड पर अब (अभी तक) केवल ध्वनि है।
आज यह कैसा दिखता है:


imageConsole 1


आर्किटेक्चर


आरेख प्रत्येक ब्लॉक में घटकों को दिखाता है और वे एक-दूसरे के साथ कैसे बातचीत करते हैं। केवल एक चीज जो नहीं दिखाई जाती है वह पीपीयू से सीपीयू से प्रत्येक फ्रेम पर एक रुकावट के रूप में संकेत है और वही संकेत जो एसपीयू में जाता है।


imageArchitecture


  • CPU: Zilog Z80 10 MHz पर
  • CPU-ROM: 8KB EEPROM, में बूटलोडर कोड है
  • CPU-RAM: 128KB RAM (56KB उपलब्ध), प्रोग्राम / गेम्स के लिए कोड और डेटा
  • IO MCU: Atmega324, CPU और RS232, PS / 2 कीबोर्ड, जॉयस्टिक और SD कार्ड फाइल सिस्टम के बीच का इंटरफेस है
  • PPU-RAM: 4-किलोबाइट दोहरी-पोर्ट मेमोरी, सीपीयू और पीपीयू के बीच मध्यवर्ती मेमोरी
  • CHR-RAM: 128KB RAM, बैकिंग (सब्सट्रेट) और स्प्राइट्स (8x8 पिक्सेल के वर्णों) के लिए डायनेमिक टाइलें संग्रहीत करता है।
  • वीआरएएम 1, वीआरएएम 2: 128 केबी रैम (43008 वास्तव में उपलब्ध है), वे फ्रेमबफ़र के लिए उपयोग किए जाते हैं, वे पीपीयू लिखते हैं और उनसे वीपीयू पढ़ते हैं।
  • PPU (पिक्चर प्रोसेसिंग यूनिट): Atmega1284, फ्रेम फ्रेमर में एक फ्रेम खींचता है।
  • VPU (वीडियो प्रोसेसिंग यूनिट): Atmega324, फ्रेमबफ़र पढ़ता है और RGB और PAL सिग्नल और सिंक्रोनाइज़ेशन उत्पन्न करता है।
  • SPU-RAM: 2KB ड्यूल-पोर्ट RAM, CPU और SPU के बीच इंटरफेस के रूप में कार्य करता है।
  • SNDRAM: 128KB RAM, FM सिंथेसाइज़र के लिए PWM पैच, PCM नमूने और निर्देश ब्लॉक संग्रहीत करता है।
  • YM3438: YM3438, एफएम संश्लेषण चिप।
  • SPU (साउंड प्रोसेसिंग यूनिट): Atmega644, पल्स चौड़ाई मॉड्यूलेशन (PWM) के सिद्धांत का उपयोग करके ध्वनि उत्पन्न करता है और YM3438 को नियंत्रित करता है।

अंतिम विनिर्देशों


सीपीयू:


  • 10Mz की आवृत्ति पर 8-बिट CPU Zilog Z80।
  • बूटलोडर के लिए 8KB रोम।
  • 56 केबी रैम।

आईओ:


  • FAT16 / FAT32 एसडी कार्ड रीडर से डेटा पढ़ना।
  • RS232 पोर्ट पर पढ़ें / लिखें।
  • 2 मेगाड्राइव / उत्पत्ति-संगत गेम कंट्रोलर।
  • कीबोर्ड PS2।

वीडियो:


  • रिज़ॉल्यूशन 224x192 पिक्सल।
  • 25 फ्रेम प्रति सेकंड (पाल से आधा एफपीएस)।
  • 256 रंग (RGB332)।
  • 2x2 आभासी पृष्ठभूमि (448x384 पिक्सेल), चार पूर्ण-स्क्रीन पृष्ठों पर आधारित द्विदिश पिक्सेल-आधारित स्क्रॉलिंग के साथ।
  • 64 ऊर्ध्वाधर और क्षैतिज फ्लिप की संभावना के साथ 8 या 16 पिक्सल की चौड़ाई और ऊंचाई के साथ स्प्राइट करता है।
  • पृष्ठभूमि और स्प्राइट प्रत्येक में 8x8 पिक्सेल के वर्ण होते हैं।
  • पृष्ठभूमि के लिए 1024 वर्णों की प्रतीकात्मक वीडियो मेमोरी और स्प्राइट्स के लिए 1024।
  • 64 स्वतंत्र क्षैतिज स्क्रॉल सेट लाइनों के साथ
  • सेट लाइनों के साथ 8 स्वतंत्र ऊर्ध्वाधर स्क्रॉल
  • वैकल्पिक रंग कुंजी पारदर्शिता के साथ 224x48 पिक्सेल ओवरले।
  • पृष्ठभूमि विशेषता तालिका।
  • SCART कनेक्टर के माध्यम से RGB और कंपोज़िट PAL।

ध्वनि:


  • 8 बिट्स और 4 चैनलों के लिए पीडब्लूएम, बिल्ट-इन वेवफॉर्म के साथ: वर्ग, साइन, आरी, शोर, आदि।
  • PWM चैनलों में से एक में 8-बिट, 8 kHz नमूने।
  • एफएम संश्लेषण चिप YM3438 50 हर्ट्ज की आवृत्ति पर निर्देशों के साथ भरी हुई है।

कंसोल के लिए विकास


कंसोल के लिए, एक बूटलोडर लिखा गया था। बूटलोडर को ROM सीपीयू में रखा गया है और यह 8 किलोबाइट तक ले जा सकता है। यह पहले 256 बाइट्स रैम का उपयोग करता है। लोडर पहली चीज है जिसे सीपीयू निष्पादित करता है। यह एसडी कार्ड पर स्थित कार्यक्रमों को दिखाने के लिए आवश्यक है।


ये प्रोग्राम फाइलों में होते हैं जिनमें संकलित कोड होता है और इसमें ग्राफिक्स और साउंड भी हो सकते हैं।


एक प्रोग्राम का चयन करने के बाद, इसे सीपीयू मेमोरी, सीएचआर मेमोरी और एसपीयू मेमोरी में लोड किया जाता है। जिसके बाद प्रोग्राम कोड निष्पादित किया जाता है। पहले 256 बाइट्स के अलावा कंसोल में लोड किए गए कोड का अधिकतम आकार 56 किलोबाइट है, और निश्चित रूप से आपको स्टैक और डेटा के लिए स्थान को ध्यान में रखना होगा।
और यह बूटलोडर और इस कंसोल के लिए लिखे गए अन्य प्रोग्राम उसी तरीके से बनाए गए थे जो नीचे वर्णित हैं।


मेमोरी / आईओ मैपिंग


इस उपसर्ग के लिए विकसित करते समय क्या महत्वपूर्ण है, यह ध्यान रखना है कि सीपीयू विभिन्न ब्लॉकों तक कैसे पहुंचता है और इनपुट इनपुट के एड्रेस स्पेस और मेमोरी के एड्रेस स्पेस को सही तरीके से आवंटित करता है।


सीपीयू बूटलोडर की रैंडम एक्सेस मेमोरी को मेमोरी के एड्रेस स्पेस के जरिए एक्सेस करता है।


मेमोरी एड्रेस स्पेस
इमेजरी चार्टिंग


और I / O एड्रेस स्पेस के माध्यम से PPU-RAM, SPU-RAM और IO MCU को।


I / O पता स्थान
इमेजियो मैपिंग


जैसा कि आप तालिका से देख सकते हैं, सभी उपकरणों, IO MCU, PPU और SPU के पते I / O पता स्थान के अंदर आवंटित किए गए हैं।


पीपीयू प्रबंधन


तालिका की जानकारी से यह देखा जा सकता है कि PPU नियंत्रण के लिए PPU मेमोरी में लिखना आवश्यक है जो I / O एड्रेस स्पेस में 1000h-1FFFh के पते पर उपलब्ध है।


PPU पता स्थान आवंटन


ImagePPU मापन


PPU स्थिति निम्न मान ले सकती है:


  1. एंबेडेड ग्राफिक्स मोड
  2. गतिशील ग्राफिक्स मोड (CHR-RAM)
  3. सीएचआर मेमोरी में रिकॉर्डिंग मोड
  4. रिकॉर्डिंग पूरी हो गई है, सीपीयू से मोड पुष्टि की प्रतीक्षा कर रहा है

यहाँ, उदाहरण के लिए, आप स्प्राइट के साथ कैसे काम कर सकते हैं:
उपसर्ग एक बार में 64 स्प्राइट्स खींच सकता है। CPU - 1004h-1143h (320 ), 5 (5 * 64 = 320):


  1. , : Active, Flipped_X, Flipped_Y, PageBit0, PageBit1, AboveOverlay, Width16, Height16.
  2. , ( ).
  3. ( — )
  4. X
  5. Y

, , Active 1, X Y , 32/32 , .


.


उदाहरण के लिए, अगर हमें स्प्राइट नंबर 10 दिखाना है, तो पता 4145 (1004h + (5 x 9)) होगा, सक्रियण के लिए मान 1 लिखें और निर्देशांक, उदाहरण के लिए, x = 100 और y = 120, पता 4148 और मान 100 लिखें। पता 4149 मूल्य 120।


कोडांतरक का उपयोग करना


कंसोल के लिए प्रोग्रामिंग विधियों में से एक कोडांतरक है।


यहां एक उदाहरण है कि कैसे एक स्प्राइट को दिखाया जाए और उसे चेतन किया जाए ताकि वह आगे बढ़े और स्क्रीन के किनारों को धक्का दे।


ORG 2100h PPU_SPRITES: EQU $1004 SPRITE_CHR: EQU 72 SPRITE_COLORKEY: EQU $1F SPRITE_INIT_POS_X: EQU 140 SPRITE_INIT_POS_Y: EQU 124 jp main DS $2166-$ nmi: ;    (NMI) ld bc, PPU_SPRITES + 3 ld a, (sprite_dir) and a, 1 jr z, subX in a, (c) ;  X inc a out (c), a cp 248 jr nz, updateY ld a, (sprite_dir) xor a, 1 ld (sprite_dir), a jp updateY subX: in a, (c) ;  X dec a out (c), a cp 32 jr nz, updateY ld a, (sprite_dir) xor a, 1 ld (sprite_dir), a updateY: inc bc ld a, (sprite_dir) and a, 2 jr z, subY in a, (c) ;  Y inc a out (c), a cp 216 jr nz, moveEnd ld a, (sprite_dir) xor a, 2 ld (sprite_dir), a jp moveEnd subY: in a, (c) ;  Y dec a out (c), a cp 32 jr nz, moveEnd ld a, (sprite_dir) xor a, 2 ld (sprite_dir), a moveEnd: ret main: ld bc, PPU_SPRITES ld a, 1 out (c), a ;   0 inc bc ld a, SPRITE_CHR out (c), a ;    0 inc bc ld a, SPRITE_COLORKEY out (c), a ;     0 inc bc ld a, SPRITE_INIT_POS_X out (c), a ;     0 inc bc ld a, SPRITE_INIT_POS_Y out (c), a ;   Y  0 mainLoop: jp mainLoop sprite_dir: DB 0 

C भाषा का उपयोग करना


आप सी भाषा का उपयोग भी कर सकते हैं, इसके लिए हमें एसडीसीसी कंपाइलर और कुछ अतिरिक्त उपयोगिताओं की आवश्यकता है।


सी कोड धीमा हो सकता है, लेकिन इसे लिखना तेज और आसान है।


यहां कोड का एक उदाहरण है जो ऊपर कोडांतरक कोड के समान है, यह एक पुस्तकालय का उपयोग करता है जो पीपीयू को कॉल करने में मदद करता है:


 #include <console.h> #define SPRITE_CHR 72 #define SPRITE_COLORKEY 0x1F #define SPRITE_INIT_POS_X 140 #define SPRITE_INIT_POS_Y 124 struct s_sprite sprite = { 1, SPRITE_CHR, SPRITE_COLORKEY, SPRITE_INIT_POS_X, SPRITE_INIT_POS_Y }; uint8_t sprite_dir = 0; void nmi() { if (sprite_dir & 1) { sprite.x++; if (sprite.x == 248) { sprite_dir ^= 1; } } else { sprite.x--; if (sprite.x == 32) { sprite_dir ^= 1; } } if (sprite_dir & 2) { sprite.y++; if (sprite.y == 216) { sprite_dir ^= 2; } } else { sprite.y--; if (sprite.x == 32) { sprite_dir ^= 2; } } set_sprite(0, sprite); } void main() { while(1) { } } 

गतिशील ग्राफिक्स


(मूल कस्टम ग्राफिक्स में। अनुमानित। प्रति)


उपसर्ग रोम में, बैकिंग के लिए टाइल्स का 1 पेज और तैयार स्प्राइट का एक और पृष्ठ है), डिफ़ॉल्ट रूप से आप केवल इस निश्चित ग्राफिक्स का उपयोग कर सकते हैं, लेकिन आप गतिशील पर स्विच कर सकते हैं।


मेरा लक्ष्य ऐसा था कि बाइनरी फॉर्म में सभी आवश्यक ग्राफिक्स तुरंत सीएचआर रैम में लोड किए गए थे, और रोम से बूटलोडर में कोड ऐसा कर सकता है। ऐसा करने के लिए, मैंने विभिन्न उपयोगी प्रतीकों के साथ सही आकार के कई चित्र बनाए:


imageSample टाइल घटक


चूंकि गतिशील ग्राफिक्स मेमोरी में 8x8 पिक्सेल के 256 वर्णों वाले 4 पृष्ठ और स्प्राइट्स के लिए समान वर्णों के 4 पृष्ठ होते हैं, इसलिए मैंने चित्रों को PNG प्रारूप में बदल दिया, डुप्लिकेट लोगों को हटा दिया:


छवि नमूना चरित्र


और फिर उसने 8x8 ब्लॉकों के साथ सभी को बाइनरी RGB332 प्रारूप में अनुवाद करने के लिए एक स्व-लिखित उपकरण का उपयोग किया।


imageGraphicsand लाइन


नतीजतन, हमारे पास पात्रों के साथ फाइलें हैं, जहां सभी वर्ण एक के बाद एक क्रमिक रूप से चलते हैं और प्रत्येक 64 बाइट्स लेता है।


ध्वनि


वेव RAW नमूने 8-बिट 8-किलोहर्ट्ज़ पीसीएम नमूनों में परिवर्तित हो गए।


PWM और संगीत पर ध्वनि प्रभावों के लिए पैच विशेष निर्देशों के साथ लिखे गए हैं।


जैसा कि यामाहा YM3438 FM सिंथेसिस चिप के लिए है, मुझे डेफ्लेमस्क नामक एक प्रोग्राम मिला है जो जेनेसिस YM2612 चिप के लिए PAL-सिंक्रोनाइज़ किया गया संगीत है, जो YM3438 के साथ संगत है।


डेफलेमास्क वीजीएम प्रारूप में संगीत का निर्यात करता है और मैं इसे अपने स्वयं के द्विआधारी प्रारूप में एक और मालिकाना उपयोगिता के साथ परिवर्तित करता हूं।


सभी तीन प्रकार की ध्वनि के सभी बायनेरिज़ को एक बाइनरी फ़ाइल में संयोजित किया जाता है, जिसे मेरा बूटलोडर एसडीएन रैम साउंड मेमोरी में पढ़ और लोड कर सकता है।


इमेजसाउंड लाइन


अंतिम फ़ाइल के लिए लिंक


द्विआधारी निष्पादन योग्य कोड, ग्राफिक्स और ध्वनि को एक पीआरजी फ़ाइल में संयोजित किया जाता है। PRG फ़ाइल में एक हेडर होता है जिसमें सब कुछ वर्णित होता है कि क्या ऑडियो और ग्राफिक डेटा है, वे कितना कब्जा करते हैं और डेटा स्वयं।


ऐसी फाइल को SD कार्ड में लिखा जा सकता है, और कंसोल बूटलोडर इस पर विचार करता है और सब कुछ उपयुक्त स्थानों पर डाउनलोड करता है और प्रोग्राम के निष्पादन योग्य कोड को लॉन्च करता है।


imagePRGander लाइन


एमुलेटर


मैंने C ++ में अपने कंसोल का एक एमुलेटर wxWidgets का उपयोग करके लिखा था ताकि इसके लिए विकसित करना आसान हो सके।


CPU को libz80 लाइब्रेरी द्वारा अनुकरण किया गया है।


डिबगिंग के लिए एमुलेटर में विशेषताएं जोड़ी गई हैं, मैं इसे किसी भी समय रोक सकता हूं और विधानसभा डिबगिंग को चरण दर चरण कर सकता हूं, सी में स्रोत कोड के लिए एक मैपिंग है यदि यह भाषा खेल के लिए उपयोग की गई थी।


ग्राफ के अनुसार, मैं वीडियो मेमोरी में, प्रतीक तालिकाओं में और सीएचआर मेमोरी में ही देख सकता हूं।


यहां डिबगिंग टूल के साथ एमुलेटर पर चलने वाले प्रोग्राम का एक उदाहरण दिया गया है।


imageEmulator डेमो


प्रोग्रामिंग डेमो


ये वीडियो टीवी के CRT स्क्रीन के उद्देश्य से एक स्मार्टफोन कैमरा के साथ शूट किया गया था, मैं अपूर्ण तस्वीर की गुणवत्ता के लिए माफी माँगता हूँ।


पीएस / 2 कीबोर्ड से प्रोग्राम करने वाला बेसिक दुभाषिया, पहले प्रोग्राम के बाद, मैं दिखाता हूं कि स्प्राइट को सक्रिय और स्थानांतरित करके I / O एड्रेस स्पेस के माध्यम से सीधे PPU मेमोरी में कैसे लिखना है:



ग्राफिक्स का एक डेमो, इस वीडियो में क्रमिक रूप से 64 16x16 स्प्राइट्स डाउनलोड करता है, बैकग्राउंड के बैकग्राउंड को डायनामिक स्क्रॉलिंग के साथ और एक ओवरले जो स्प्राइट्स के नीचे और ऊपर चलता है:



साउंड डेमो YM3438 और PWM साउंड की क्षमताओं को दर्शाता है, इस डेमो और एफएम म्यूजिक का साउंड डेटा और PWM साउंड मेमोरी के लगभग सभी उपलब्ध 128 किलोबाइट पर एक साथ लगता है।



टेट्रिस, लगभग विशेष रूप से पृष्ठभूमि की विशेषताएं, वाईएम 3438 पर संगीत, पीडब्लूएम पैच पर ध्वनि प्रभाव ग्राफिक्स के लिए उपयोग किया गया था।



निष्कर्ष


यह परियोजना वास्तव में एक सपना सच है, मैं कई वर्षों से इस पर काम कर रहा था, रुकावटों के साथ, अपने खाली समय को देखते हुए, मैंने कभी नहीं सोचा था कि मैं अपना गेम रेट्रो वीडियो कंसोल बनाने में इतनी दूर जाऊंगा। स्वाभाविक रूप से, यह बिल्कुल सही नहीं है, मैं निश्चित रूप से इलेक्ट्रॉनिक्स में विशेषज्ञ नहीं हूं, सेट-टॉप बॉक्स में स्पष्ट रूप से बहुत सारे तत्व थे, और निस्संदेह कोई बेहतर कर सकता था और शायद कुछ पाठक इसके बारे में सोच रहे हैं।


लेकिन फिर भी, इस परियोजना पर काम करने की प्रक्रिया में, मैंने इलेक्ट्रॉनिक्स, गेम कंसोल और कंप्यूटर डिज़ाइन, असेंबली लैंग्वेज और अन्य दिलचस्प चीजों के बारे में बहुत कुछ सीखा, और सबसे महत्वपूर्ण बात, मुझे गेम खेलने में बहुत संतुष्टि मिली जिसे मैंने खुद हार्डवेयर पर लिखा था जिसे मैंने खुद विकसित किया था। और एकत्र किया।


मेरे पास कंसोल / कंप्यूटर और अधिक बनाने की योजना है। वास्तव में, मैं पहले से ही एक नया सेट-टॉप बॉक्स बना रहा हूं, यह लगभग तैयार है, और यह FPGA बोर्ड पर आधारित एक सरलीकृत रेट्रो सेट-टॉप बॉक्स है और कई अतिरिक्त घटक (इस परियोजना की तुलना में बहुत कम राशि में, निश्चित रूप से), विचार बहुत सस्ता और अधिक दोहराने योग्य है।


हालाँकि मैंने इस प्रोजेक्ट के बारे में यहाँ बहुत कुछ लिखा है, निस्संदेह इस पर चर्चा की जा सकती है, मैंने बमुश्किल उल्लेख किया है कि साउंड इंजन कैसे काम करता है, सीपीयू इसके साथ कैसे इंटरैक्ट करता है, और बहुत कुछ है जो ग्राफिक्स सिस्टम और अन्य इनपुट्स / आउटपुट और पूरे कंसोल के बारे में किया जा सकता है। बताना होगा।


पाठकों की प्रतिक्रिया को देखते हुए, मैं अपडेट पर ध्यान केंद्रित करने वाले अधिक लेख लिख सकता हूं, व्यक्तिगत उपसर्ग ब्लॉक या अन्य परियोजनाओं के बारे में विवरण।


परियोजनाओं, साइटों, Youtube चैनलों ने मुझे प्रेरित किया और तकनीकी ज्ञान के साथ मेरी मदद की:


इन साइटों / चैनलों ने न केवल प्रेरित किया, बल्कि इस परियोजना पर काम के दौरान आने वाली जटिल समस्याओं के समाधान खोजने में भी मेरी मदद की।



यहाँ तक पढ़ने के लिए धन्यवाद। :)


यदि आपके पास कोई प्रश्न या प्रतिक्रिया है, तो कृपया नीचे टिप्पणी में लिखें (अंग्रेजी में मूल लेख Github। Approx। Per)

Source: https://habr.com/ru/post/hi444006/


All Articles