home.social

Search

916 results for “0x0”

  1. In revisiting some old #APT37 samples, I wanted to take a look back at the #GOLDBACKDOOR dropper. Which actively targeted civil society & journalists based in South Korea.

    Here's in my reverse engineering analysis, I deep dive into this older malware campaign by the North Korean threat group.

    This is part of my project REarchive, where I look at historic APT campaigns that haven't been covered much publicly. Read here:
    0x0v1.com/rearchive-goldbackdo

    #malware #APT #northkorea #threatintel #reverseengineering

  2. Just uploaded my #APT37 #ROKRAT shellcode decrypter script to my github. Hope this helps malware researchers out there

    github.com/0x0v1/MalwareRETool

  3. I just published a script that will assist malware researchers looking at #APT37's #ROKRAT to decode the PS reflection portion of the loader phase. It gives analysts the option to pull shellcode from the payload delivery host quickly for timely analysis.

    github.com/0x0v1/MalwareRETool

    I will later publish a script to deencrypt the shellcode for analysis - just need to clean a few things up in it.

  4. @erlend @jackwilliambell @elipariser @dev @0x0
    We don't know if our #GlutPlug proposal is of interest here. Its for Fediverse #resilience so as fediverse scales instances don't have to shutdown due to overwhelming demands for content.

    When a person boosts likes or replies to content they've downloaded they will also host it themselves for as long as it is in demand, over one of the three #I2P addresses provisioned for such. Server tells subsequent viewers to fetch content from these #I2Peers.

  5. I need #NetApp #FollowerPower...

    I've got a disk that fell out of the storage accidentally after I moved the system inside of the rack. i.e.: the disk popped out and when the shelf was powered on again, it detected missing disk.

    When pushing the disk back in and fastened it again, the system don't want to unfail the disk again.

    Putting the SAS disk into a Linux box fails as well, because 520bytes vs. 512bytes.... yada, yada...

    Any tips how to deal with that situation?

    PS: under Linux I get this error when I put the disk in:

    megaraid_sas 0000:0b:00.0: 305268 (825169084s/0x0002/FATAL) - Unable to access device PD 18(e0x08/s11)

    The disk is then not recognized by the system (no /dev/sg* device, not listed by lsscsi).

  6. Gestern ist Episode 104 online gegangen.
    Dieses Mal hat sich Sven aufgrund mehrerer Empfehlungen das tool winget angesehen und erzählt mir was das ist.
    Wie immer gibt es auch viel am Rande zu News, Datenverlusten, Hausmeister-Info und am Schluss noch ein wenig spaß.

    0x0d.de/2023/03/0d104-mehr-sic

    #zeroday #podcat #securiy #datenschutz #windows #Winget #paketmanager #datenverlust #news #informationssicherheit #dsgvo

  7. @nazokiyoubinbou
    #Slackware, @Devuan, and #Antix are free by design.
    #Gentoo, to me, had the best approach: gives you choice of init system.
    @itsfoss

  8. Компьютерная криминалистика: дополнительный поиск ВПО при помощи событий Windows Defender

    Привет, Хабр! На связи команда uFactor. В этой статье рассмотрим полезный способ поиска ВПО, который может быть дополнением к анализу компьютерных систем при расследовании инцидентов информационной безопасности. Увы, этот способ не всегда эффективен: следы активности Windows Defender, рассматриваемой далее, имеют свойство полностью удаляться — именно поэтому способ может использоваться только в качестве дополнения к основному методу исследования. Многие используют в своих расследованиях анализ журналов событий `Event ID 1116, Event ID 1117 Windows Defender`, а также записи и файлы из карантина. Мы же поговорим о событиях сканирования файлов Windows Defender, которые пользователь скачивает, либо которые по иной причине появились в компьютерной системе. Артефакты, указывающие на сканирование Windows Defender, хранятся в виде файлов, например: `.\ProgramData\Microsoft\Windows Defender\Scans\History\Results\Resource\ {8C9221F8-4026-473E-A0B6-3D6981F102F0}`. В журнале `Microsoft-Windows-Windows Defender` вы не увидите событий сканирования, если файл не получил статус вредоносного ПО. Имена файлов имеют вид UUID версии 4 согласно стандарту RFC 4122. Эти имена не несут в себе полезной информации, в отличие, например, от имен UUID версии 1 (анализирующихся в нашей статье «Компьютерная криминалистика. Временные метки и туннелирование NTFS» ). Содержимое файлов зашифровано алгоритмом RC4 со следующим ключом: `0x1E, 0x87, 0x78, 0x1B, 0x8D, 0xBA, 0xA8, 0x44, 0xCE, 0x69, 0x70, 0x2C, 0x0C, 0x78, 0xB7, 0x86, 0xA3, 0xF6, 0x23, 0xB7, 0x38, 0xF5, 0xED, 0xF9, 0xAF, 0x83,

    habr.com/ru/companies/usergate

    #usergate

  9. So we are now playing musical cloud outage chairs now?

    #cloudoutage #ItsDNS

  10. So we are now playing musical cloud outage chairs now?

    #cloudoutage #ItsDNS

  11. So we are now playing musical cloud outage chairs now?

    #cloudoutage #ItsDNS

  12. So we are now playing musical cloud outage chairs now?

    #cloudoutage #ItsDNS

  13. Mini Listening Post

    One of the most fascinating pieces of electronic artwork I’ve seen is Mark Hansen and Ben Rubin’s Listening Post when it was on display at the Science Museum, London.

    Designed in the early 2000s it was on display from around 2008 for a number of years, but unfortunately it has been packed away in storage amongst the museum’s collections now for some time.

    https://www.youtube.com/watch?v=Rzfnndd9fCk

    You can read about it on the following links:

    The original has 3 PCs, a Mac and 231 (11 rows of 21) embedded modules each with a four-line text display. As well as the visuals there is a complex surround audio experience of sound and synthesized speech coming out of 10 or more speakers. Each embedded module also has a clicking relay which can create the impression of an older flip display working.

    The videos that can be found online really don’t do it justice. There is nothing quite like sitting in front of it with the sound coming at you from all sides.

    By the way, it is called Listening Post as it taps into live forums and IRC and pulls out text for the display. It is literally showing a snapshot of the global conversations as they happen – swearing and all. In fact, I recall a “parental controls” warning prior to going into the display, to that effect.

    I’ve often wondered if a small part of it could be reproduced in a simpler form, so have started a series of blog posts listing some experiments working towards that idea.

    The original is pretty amazing and a serious implementation, with a huge does of imagination and creativity. It would take an awful lot of effort to get anywhere close to something similar, so I’m not aiming for anything even close to that. But I’m going to keep fiddling around on and off to see if I can get something a lot more limited going at a smaller scale that might at least be considered to be in the spirit of the original somehow.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    The Display Modules

    My starting point is my Waveshare Zero Multi Display PCB Design and Expander Board.

    The original has 231 small embedded modules, each with a Vacuum Fluorescent Display (VFD) that displays the text. There are two modes for the text: a four-line smaller display, and a large character scrolling display. Each of these options seems to be a function of the type of display in use, which I believe to be a VFD 420.

    There is a data sheet and programmers guide for the VFD 420 here:

    The VFD 420’s normal display mode looks like this:

    The programmers guide describes the “big character” mode as follows:

    “VFD-420’s “Big-character” mode can generate full-screen-height numbers and letters (uppercase only)—up to four letters/digits per screen. Big-mode symbols—consisting of dot/decimal point (.), hyphen/minus sign (-), colon (:) and space—take up one-half the width of other “big” characters.”

    It does seem possible to buy similar displays today, but what I have seen so far are very, very expensive! I did temporarily wonder about the 4-line version of the HD44780 20×2 character displays. I might still come back to that at some point.

    But for now, the trick for me is to attempt to reproduce the look and feel of the VFD big character display with my ST7789 SPI displays used with my Waveshare Zero Multi Display.

    I spent a bit of time studying various videos of the Listening Post in action and started to sketch out the main characters that I’d require to rebuild the big character font.

    It looks like the originals have a 4×4 matrix of small characters per big character. And each small character is a 8×5 grid and of course there are 20 of these for each of the four lines of the display.

    I decided I could probably get away with 10 characters in total.

    The Code

    I’ve opted for a class that implements the “large text LCD” that effectively drives the TFT display. There are functions for each of the 10 character patterns shown above. Each of these uses the primitives from the Adafruit GFX library to construct the 10 glyphs using filled rectangles or sequences of lines. For example:

    // "bottom left triangle"
    void CLCD2004::botLTri (uint16_t x, uint16_t y, uint16_t colour) {
    uint16_t xlen = 0;
    for (int i=1; i<CHAR_H; i++) {
    m_pdisplay->drawFastHLine(1+x*CHAR_W, i+y*CHAR_H, xlen/10, colour);
    xlen = xlen + (CHAR_W*10-1)/CHAR_H;
    }
    }

    From there, I’ve built a set of functions that look up which characters are required for each bt character and gets them on the display one row at a time.

    void CLCD2004::printbigchar (char c, uint16_t x, uint16_t colour) {
    c = c - LCD2004FONT_START;

    printglyph (lcd2004font[c][0], x*BIGCHAR_X, 0, colour);
    printglyph (lcd2004font[c][1], x*BIGCHAR_X, 1, colour);
    printglyph (lcd2004font[c][2], x*BIGCHAR_X, 2, colour);
    printglyph (lcd2004font[c][3], x*BIGCHAR_X, 3, colour);
    }

    void CLCD2004::printglyph (uint16_t g, uint16_t x, uint16_t y, uint16_t colour) {
    if (g & 0xF000) {
    printchar('0' + (g>>12 & 0xF), x, y, colour);
    }
    if (g & 0x0F00) {
    printchar('0' + (g>>8 & 0xF), x+1, y, colour);
    }
    if (g & 0x00F0) {
    printchar('0' + (g>>4 & 0xF), x+2, y, colour);
    }
    if (g & 0x000F) {
    printchar('0' + (g & 0xF), x+3, y, colour);
    }
    }

    void CLCD2004::printchar (char c, uint16_t x, uint16_t y, uint16_t colour) {
    switch (c) {
    ... case '0' to '5' ...

    case '6':
    botLTri(x, y, colour);
    break;

    ... case '7' to '9' ...
    }
    }

    There is a font definition that has each block of four characters stored as a 32-bit value for all ASCII characters from 0 through to Z.

    Everywhere a 6 occurs in the table, that will trigger the above botLTri() function to draw a “bottom, left, triangle”.

    const uint16_t lcd2004font[LCD2004FONT_SIZE][4] = {
    {0x7446,0x1001,0x1001,0x9558}, // 0
    {0x0720,0x0320,0x0320,0x0110}, // 1
    {0x7446,0x0078,0x0780,0x7111}, // 2
    ...
    {0x0760,0x7896,0x1441,0x1001}, // A
    {0x1446,0x1558,0x1446,0x1558}, // B
    {0x7446,0x1000,0x1000,0x9558}, // C
    ...
    {0x4441,0x0078,0x7800,0x1555}, // Z
    };

    Finally I can now wrap this all up in a general print routine.

    void CLCD2004::print (char *c) {
    uint16_t xc = 0;
    while ((c[xc] != 0) && (xc < MAX_BIGCHAR_X)) {
    printbigchar (' ', xc, m_bg);
    printbigchar (c[xc], xc, m_fg);
    xc++;
    }
    }

    Using this class is now a case of setting up the TFT display and LCD objects for each screen.

    SPIClass MySPI(FSPI);
    Adafruit_ST7735 tft1 = Adafruit_ST7735(&MySPI, TFT_CS1, TFT_DC, TFT_RST);
    CLCD2004 lcd((Adafruit_ST77xx*)&tft1, ST_WHITE, ST_BLACK);

    void setup() {
    MySPI.begin(SPI_SCLK, SPI_MISO, SPI_MOSI, SPI_SS);

    tft1.initR(TFT_TYPE);
    tft1.setSPISpeed(SPI_SPEED);
    tft1.setRotation(3);
    tft1.fillScreen(ST_BLACK);
    }

    void loop() {
    lcd.setColour(ST_CYAN, ST_BLACK);
    lcd.printclr();
    lcd.print("ABCD");
    }

    To create the scrolling is a bit more complex. To do that I decided to add the following:

    • A “scrolled” parameter to the display.
    • Use a GFX canvas to maintain a pixel bitmap in memory and write to that.
    • Add an update() function to draw the bitmap over to the display.
    • Expand the print functions to accept a longer string that is stored in a buffer ready to be printed to the canvas.
    • Add a scroll function that determines where in the string the updating/printing starts.

    There were a few things I had to sort out to get this working.

    1. The writing of an RGB bitmap to the display was really slow. This is because the provided function has additional SPI writes per pixel that could actually be done just one. This resulting in my writing my own more optimised version of drawRGBBitmap.
    2. It turns out that setting the SPI speed has to be performed after the initialisation of the display object (i.e. call setSPISpeed() after calling initR()).
    3. Getting the correct “windowing” to allow the scrolling effect was quite tricky.
    4. As the display shows four big characters, I always print five on the canvas and let the scroll work, via the windowing, for a whole character. Then a new set of five characters gets printed, and the scroll position resets again.
    5. The fastest supported SPI speed for the ESP32S3 is 80MHz and it often works at that speed. But occasionally one of the displays will be a bit glitchy, so a slower speed is advisable. I’ve been using 60MHz. I don’t know if that translates to a legitimate SPI speed or not, so the driver may be rounding that to something more sensible – I don’t know!

    The basic operation is now:

    Set up SPI, TFT and the LCD.
    Print a character string to the LCD.
    Calling update() will put the first part of the string on the display.
    Calling scroll() will shift it as required.

    The scroll() function has an option to wrap back to the first character in the string if required.

    The Results so far

    It has taken a bit of tweaking but I believe I can get useful performance out of a single ESP32S3 driving eight SPI displays.

    The original has many display modes, so I went with starting to model one of the simpler modes – it searches for the phrase “I am” and then displays what follows. This mode can be seen in action in the video at the end of this post.

    For now, to show the display as potential, I’m just printing the two words “I AM”. This video shows the hard-coded “I AM” display in action with a randomised start time and scroll speed for each display.

    https://makertube.net/w/hnxY9deqZm1CWCufjS6A4Z

    Find it on GitHub here.

    Closing Thoughts

    As I say, the original has many display modes, but there is something quite hypnotic about the “I AM” mode that I like. It would be nice to find a way to hook this up to Mastodon searching for uses of the phrase.

    So this is starting small, but getting the font in an acceptable format is quite a key part of this project doing anything useful for me. I think this is a really useful start.

    Kevin

    https://www.youtube.com/watch?v=dD36IajCz6A

    #ESP32s3 #ListeningPost #VFD

  14. SP0256A-AL2 Sings the Twelve Days of Christmas

    Partly prompted by a programming challenge by Futzle on Mastodon, I thought it might be interesting to try to get my Arduino and SP0256A-AL2 to sing the Twelve Days of Christmas.

    https://makertube.net/w/diBkzrhkh3tekAPBhGzrVj

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    These are the key Arduino tutorials for the main concepts used in this project:

    If you are new to Arduino, see the Getting Started pages.

    Parts list

    The Code

    I wasn’t aiming for a clever code solution, as can be seen submitted to the programming competition already, but I was hoping to get the computer to do at least some of the work for me.

    The first issue is getting a useful range for the song. My original MIDI SP0256 project managed around an octave and a half. Well it so happens that the 12 Days of Christmas is just over 1 octave, so if I can position that to the top end of the range, I should be ok.

    This is the most compact notation of the tune that I know of. This is from the “Christmas Praise” Brass Band carol book, which seems to be one of the most common references for any band out caroling at this time of year.

    Ignoring the introduction, I’m going to transpose this into concert Bb (i.e. up a minor third) which gives me a note range from F2 through to G3. This allows me to use a sensible range of the SP0256A without it getting too slow down at the bottom end of things.

    The main text/lyric structure will be set up in a series of functions as follows:

    intro() - "on the nth day of Christmas my true love gave to me"
    nth() - "first", "second", etc.
    one() - "a partridge in a pear tree"
    two() - "two turtle doves"
    ...
    twelve() - "twelve drummers drumming"

    Some variations are required as follows:

    • intro() – needs to be able to switch to “and a partridge” for all verses apart from verse 1.
    • two(), three(), four() – have a different melody from verse 5 onwards.
    • five() – ideally this should get slower and more drawn out with each repetition.
    • one() – ideally this would slow down on the last time through.

    In order to capture the variations and repeats for each verse, I’ve opted to use an increasing bitmask for each time through to trigger the various phrases. Bit 0 always indicates one() must be called. Bit 1 indicates two(), and so on. It starts with the value 1 but will keep adding another bit as the verses change, so will have the values 1, 3, 7, 15, 31, 63, etc. thus allowing me to build up the verses with one bit per verse.

    one() takes bool parameters to indicate first time and last time through. two(), three(), four() take a bool parameter to indicate if it is a “post five gold rings” verse. Using the bitmask this is pretty easy as it just means any of the bits 0x0FF0 will be set for verses 5+.

    Here is the main code loop.

    uint16_t phrase=1;
    for (int verse=1; verse<=12 ; verse++) {
    intro(verse);
    delay(200);
    if (phrase & 0x0800) twelve();
    if (phrase & 0x0400) eleven();
    if (phrase & 0x0200) ten();
    if (phrase & 0x0100) nine();
    if (phrase & 0x0080) eight();
    if (phrase & 0x0040) seven();
    if (phrase & 0x0020) six();
    if (phrase & 0x0010) five(verse);
    if (phrase & 0x0008) four(phrase & 0x0FF0);
    if (phrase & 0x0004) three(phrase & 0x0FF0);
    if (phrase & 0x0002) two(phrase & 0x0FF0);
    if (phrase & 0x0001) one(phrase == 1, verse == 12);
    phrase = (phrase<<1) + 1;
    delay(1000);
    }

    The timings were really quite tricky as I have several variables to work to:

    • Each allophone takes a different time to be said.
    • Each allophone also has a recommended delay time (this might be to account for the time to say them – I’m not sure).
    • When I change the frequency, the time to say any specific allophone also changes, with lower frequencies significantly slower than higher ones.
    • I naturally need to account for the musical rhythm changes too.

    In principle I could probably work out the slowest interval and work back from there to get some accurate timings, but I just did a bit of trial and error on each phrase until it was close enough. The unevenness remaining was because I didn’t want to slow the whole thing down to the slowest phrases being “sung”. It is slow enough already!

    Also, as it doesn’t look much, I’ve added an LED to light up at the start of an allophone and to go off whenever a pause is encountered.

    Find it on GitHub here.

    Closing Thoughts

    I’m actually really pleased with this. It is a good balance of close enough to show the principle without me undertaking complex timing and endless fiddling.

    I could probably get a bit cleverer with the code, but that wasn’t really the point for me. I’ve used an algorithm where it mattered to me, and was quite happy to spell out the allophones, frequencies, and timings by hand as I went.

    Lastly, let me wish you the compliments of the season, to you and yours.

    Kevin

    #arduinoUno #sp0256aAl2

  15. Atari Synth Cart Controller

    This project uses my Atari 2600 Controller Shield PCB in reverse, to allow the Arduino to act as an Atari keypad controller and thus allow it to control the Atari Synth Cart.

    https://makertube.net/w/ryCciwFyQQpcs1Q4Wwy52x

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    These are the key Arduino tutorials for the main concepts used in this project:

    If you are new to Arduino, see the Getting Started pages.

    Parts list

    The Circuit

    In this use of my Atari 2600 Controller Shield PCB the 9-pin d-type connectors are directly connected to the Atari console.

    There is one issue however. Which device should provide 5V? The Atari pinout has 5V present on pin 7 and this is hooked up to the Arduino 5V line.

    It may be possible to run the Arduino off the Atari 5V line, which would be really convenient if so. But I’ve not found a definitive statement of the maximum current draw through the 5V pin of the d-type connector from an Atari 2600.

    From the schematics for the 2600, it appears that the 5V comes directly from a 7805 regulator. This may or may not go via a single inductor depending on what version of the schematic I’m looking at (yes, for the schematics on Atari Age, below, no for the schematic in the field service manual).

    From the BOM in the field service manual, this would appear to be a 78M05 which I believe has a maximum current output of 500mA with a suitable heatsink.

    But that has to power the entire console of course. In a not particularly scientific measurement, I believe my 2600 jnr was drawing around 360mA and my “woody” perhaps around 320mA. I don’t know how this changes with different games or controllers.

    According to this post, an Arduino Uno with no IO pin current draw, will pull around 50mA when powered from the 5V line directly. Curiously, a bare-bones ATMega328P can apparently drop to almost 15mA when not driving regulators, a USB chip and a power LED…

    From powering up a number of Arduino projects I had lying around, most hardly registered on a simple USB current meter using 10mA units. Some with LEDs got to show 0.02A. Some with screens got up to 0.2A.

    So just thinking about it in a somewhat hand-wavy kind of way, I suspect that powering an Uno would probably be ok…

    If not, then the 5V line to the d-type connectors will have to be cut and the Arduino independently powered. But then the signals for the keypad will be set at the Arduino’s idea of what 5V looks like, not the Atari. They ought to be essentially the same, but it can’t be guaranteed.

    Ideally to go this route, the Arduino would isolated from the Atari and be switching the Atari’s 5V line on and off for the input signals as required, but that would require a new design of the PCB.

    So time for an IMPORTANT WARNING: This could well damage the Atari 2600 console as I’m essentially making it up as I go at this point.

    I have a cheap Atari 2600 junior that I picked up a while back that I’m happy to experiment with. I’m not using my own, original “woody”. In the end I used the following:

    Volca <– 3.5 mm jack to jack –> Arduino TRS MIDI + Atari Shield <– 9-pin to 9-pin –> 2600

    Here is the full setup using a Video Touch Pad as the second controller. Note the Arduino is fully powered from the Atari at this point, but the Volca is running on batteries.

    The Code

    The basic principle for the Arduino is to monitor the Atari’s “row” signals via INPUT pins and when detected drive any OUTPUTs LOW to indicate keys being pressed. The basic algorithm is as follows:

    rows[] = IO INPUT pins connected to D-type pins 1, 2, 3, 4
    cols[] = IO OUTPUT pins connected to D-type pins 5, 6, 9

    FOREACH row[]:
    IF row is scanning LOW THEN
    Set cols[] HIGH or LOW in turn according to required keypress

    REPEAT for second controller

    The keypad row/column map was shown in Arduino Atari MIDI Keypad and reproduced here:

    Active (pressed) keys will show as LOW in a column when that row is scanned, so to emulate 6 being pressed, when row on pin 2 is detected as being LOW, column on pin 6 should be driven LOW and columns on pins 5 and 9 should be driven HIGH.

    I need to map these keys over onto MIDI notes. One issue is that the Atari doesn’t have a natural scale as generating the frequencies for notes is pretty limited.

    Still, I’ve mapped the 12 keys, with their non-natural scale, over onto MIDI notes 60-71 – i.e. all semitones up from middle C.

    I’m using PORT IO in an interrupt driven scanning routine to ensure the Arduino is as responsive as it can be to ROW scanning. I also pre-compute the actual column bit values when a MIDI note is received, meaning the scanning routine only has to write out the preset values.

    The main functions that achieve this are shown below, with the PORT IO values set up for the second Atari controller connector on my Atari 2600 Controller Shield PCB.

    uint8_t row[ROWS];
    uint8_t colbits[COLS] = {
    0x02, // C0 = A1 PORTC
    0x01, // C1 = A0 PORTC
    0x10 // C2 = D12 PORTB
    };

    void keyOn (int r, int c) {
    if (r < ROWS && c < COLS) {
    // Clear the bit as need active LOW
    row[r] &= (~colbits[c]);
    }
    }

    void keyOff (int r, int c) {
    if (r < ROWS && c < COLS) {
    // Set the bit as need active LOW
    row[r] |= colbits[c];
    }
    }

    void scanKeypad (void) {
    // ROWS: D11-D8 = ROW1-ROW4
    if ((PINB & 0x08) == 0) { // D11
    PORTB = (PORTB & (~0x10)) | (row[0] & 0x10); // COL D12
    PORTC = (PORTC & (~0x03)) | (row[0] & 0x03); // COL A0, A1
    }
    if ((PINB & 0x04) == 0) { // D10
    PORTB = (PORTB & (~0x10)) | (row[1] & 0x10);
    PORTC = (PORTC & (~0x03)) | (row[1] & 0x03);
    }
    if ((PINB & 0x02) == 0) { // D9
    PORTB = (PORTB & (~0x10)) | (row[2] & 0x10);
    PORTC = (PORTC & (~0x03)) | (row[2] & 0x03);
    }
    if ((PINB & 0x01) == 0) { // D8
    PORTB = (PORTB & (~0x10)) | (row[3] & 0x10);
    PORTC = (PORTC & (~0x03)) | (row[3] & 0x03);
    }
    }

    As the Synth Cart notes are mostly controlled from the left controller, I’m only coding up for the Arduino to drive one controller. I’m using a genuine Video Touch Pad for the second controller.

    Update: The code now includes a controller pass-through mode. If a keypad is plugged into the second socket on the Arduino, then either MIDI or the keypad can be used to drive the Synth Cart.

    To achieve this, there are now two sets of row[] arrays containing the column values and when it comes to writing them out, they are combined as follows:

    if ((PINB & 0x08) == 0) {  // D11
    PORTB = (PORTB & (~0x10)) | (row[0][0] & row[1][0] & 0x10);
    PORTC = (PORTC & (~0x03)) | (row[0][0] & row[1][0] & 0x03);
    }

    As the signals are active LOW, the two values need to be logically ANDed together to get the correct result. I could have simply called the same noteOn/noteOff routines for the keypad, but then I’d have the situation where if both keys for a note are active, the first one released will stop the sound. By combining them in this way, the note will keep sounding until both keys are released.

    Find it on GitHub here.

    Closing Thoughts

    I really ought to map the pitches of the Atari notes onto their respective MIDI notes, but then I’m not sure what to do for the gaps.

    In principle I could wire up both controllers and then use MIDI pads on a MIDI controller just as MIDI-driving control keys rather than actual keyboard notes, but this shows the principle.

    I’m still not sure about the power issues, but it seems to work. I guess it will keep working until one day it might not and I’ll be looking for a new Atari 2600 junior.

    The slight stuttering in the video is when I end up touching a couple of the volca’s keys at the same time. I suspect I could do something a bit more robust in code to prevent repeat triggering, but this is all fine for now as a proof of concept.

    Kevin

    #arduinoUno #atari #atari2600 #midi #synthcart

  16. TD4 4-bit DIY CPU – Part 7

    Once the idea was floated, in Part 6 of creating an Arduino “direct to ROM” assembler, I had to just do it, so this post is a little diversion from the hardware discussion into how that could work.

    • Part 1 – Introduction, Discussion and Analysis
    • Part 2 – Building and Hardware
    • Part 3 – Programming and Simple Programs
    • Part 4 – Some hardware enhancements
    • Part 5 – My own PCB version
    • Part 6 – Replacing the ROM with a microcontroller
    • Part 7 – Creating an Arduino “assembler” for the TD4

    Basic Concepts

    This relies on using an Arduino as the ROM as described in Part 6, but the Arduino now has the option to change the ROM contents independently of the TD4 itself.

    The Arduino sketch will do the following:

    • Run the TD4 ROM routine off a timer interrupt so that it is always running and responsive.
    • Take input over the Arduino serial port to allow basic control, e.g. list, clear, etc.
    • Allow the direct input of assembler instructions, such as MOVE A,B or OUT B and so on.
    • Provide a means of selecting which line of the program to change.

    The code will thus have a number of key sections:

    • The TD4 ROM routine.
    • Some kind of serial-port command-line interpreter.
    • Handler routines for all the commands.
    • An assembler.
    • A disassembler.

    The TD4 ROM routine has already been fully described in Part 6. The only difference is that the scanning routine will be driven from a 1mS timer using the TimerOne library.

    As I want to still support a built-in demo, I now have the concept of ROM being the demo code and RAM being the “live” code to pass onto the TD4. The Arduino will initialise the RAM on startup from the ROM.

    As far as the TD4 is concerned of course, this is all still ROM.

    Command Line Interpreter

    The standard Arduino Serial routines will be used to scan for input via the serial port. It will support a line-oriented input as follows:

    bool cmdRunner (void) {
    while (Serial.available()) {
    char c = Serial.read();
    if (c == '\n') {
    strcpy(cmdSaved, cmdInput);
    cmdIdx = 0;
    return true;
    }
    else if (cmdIdx < CMD_BUFFER-1) {
    cmdInput[cmdIdx++] = c;
    cmdInput[cmdIdx] = '\0';
    }
    }
    return false;
    }

    This will keep adding any received characters to the cmdInput buffer until a newline is received, at which point the command is saved in cmdSaved and the routine will return true indicating a full line is ready to be processed.

    Once a complete line is received, then a processing function will parse it.

    Key to the processing of commands is a command table that stores the text to match and the handler function to call on finding a valid command. There is an additional parameter that will be passed into the handler function to allow the same handler function to support several commands. This will be used in the assembler itself later.

    struct cmd_t {
    char cmd[CMD_BUFFER+1];
    hdlr_t pFn;
    uint8_t idx;
    };

    const cmd_t PROGMEM cmdTable[NUM_CMDS] = {
    {"H", hdlrHelp, 0},
    {"L", hdlrList, 0},
    {"G", hdlrGoto, 0},
    };

    The algorithm for parsing commands is as follows:

    cmdProcess:
    Look for a space or newline
    IF found a space THEN
    This is the start of the parameter

    Look for the command in the command table
    IF command found THEN
    Call the handler function with the parameters

    The implementation is a bit complex, as it uses string pointers and has to chop and parse strings as it goes. It is also detailing with the command table in the Arduino’s PROGMEM which is an additional complication too.

    In order to be able to use the same command line interpreter for the input of assembler instructions, I’ve had to simplify the syntax. There are no spaces in opcodes and there has to be a space between the opcode and immediate value if used.

    Here are some examples:

    IN A       -> INA
    MOVE A,B -> MOVAB
    OUT im -> OUT im
    JNC im -> JNC im
    ADD A,im -> ADDA im

    Handler Routines

    All handler routines have the following prototype:

    typedef void (*hdlr_t)(int idx, char *param);

    void hdlrHelp(int idx, char *pParam) {
    Serial.print("\nHelp\n----\n");
    Serial.println("H: Help");
    }

    The idx parameter is the number in the last field of the command table. pParam will be a pointer to the parameter string for the command (if used).

    As we’re dealing with strings all the time, there are a number of helper functions to do things like convert strings to numbers as well as others to print numbers in various formats.

    Number formats are assumed to be as follows:

    0..9   - decimal digits
    0x0..F - hex digits
    b0..1 - binary digits

    The code provides the following:

    • str2num – the basic string parsing routine to recognise all three number formats as strings.
    • printbin – print a number in b0..1 format.
    • printhex – print a number in 0x0..F format, allowing for a possible leading zero if required.
    • printins – print an instruction in textual format.
    • printop – print an instruction in binary and hex opcode format.
    • printline – print a line number in a consistent binary and hex format.

    The code supports the following commands, so each has its own handler function:

    • H – help – show the list of commands.
    • L – list – show the disassembly of the whole working memory (RAM).
    • G – goto – set the working line number.
    • C – clear – reset all working memory (RAM) to zeros.
    • R – restore – restore the working memory (RAM) to the pre-build demo code (ROM).
    • O – opcodes – list the supported opcodes.

    Assembler

    As already mentioned, I’m using the same command line interpreter code to create the assembler. To do this, each opcode has an entry in the command table:

    const cmd_t PROGMEM cmdTable[NUM_CMDS] = {
    // Assembly commands - must be first
    {"ADDA", hdlrAsm, 0},
    {"MOVAB", hdlrAsm, 1},
    {"INA", hdlrAsm, 2},
    {"MOVA", hdlrAsm, 3},
    {"MOVBA", hdlrAsm, 4},
    {"ADDB", hdlrAsm, 5},
    {"INB", hdlrAsm, 6},
    {"MOVB", hdlrAsm, 7},
    {"OUTB", hdlrAsm, 8},
    {"OUT2B", hdlrAsm, 9},
    {"OUT", hdlrAsm, 10},
    {"OUT2", hdlrAsm, 11},
    {"JNCB", hdlrAsm, 12},
    {"JMPB", hdlrAsm, 13},
    {"JNC", hdlrAsm, 14},
    {"JMP", hdlrAsm, 15},

    // Other commands
    {"H", hdlrHelp, 0},
    {"L", hdlrList, 0},
    {"G", hdlrGoto, 0},
    {"C", hdlrClear, 0},
    {"R", hdlrRestore, 0},
    {"O", hdlrOpcodes, 0},
    };

    The order corresponds to the opcode command value, as does the parameter. As these are at the start of the table, I can assume that the position in the table is the same as the command value. This does mean that I also need to account for the duplicated instructions even if I don’t need to use them.

    I’m making the following design decisions:

    • There is the concept of a “current line” which can be set with the G (goto) command.
    • Entering a valid opcode automatically moves the current line on by 1.
    • No line information is entered as part of the opcode.

    The main logic of the assembler handler is as follows:

    Assembler:
    Command value is the provided index parameter
    Determine the im value from the provided string parameter
    RAM[line] = cmd << 4 + im
    Increment current line

    Disassembler

    Disassembly is really largely a look-up table matching opcode command values to text. This is all hidden away behind the two print routines printins() and printop().

    void printins (uint8_t ins) {
    uint8_t cmd = ins >> 4;
    uint8_t im = ins & 0x0F;

    Serial.print(FSH(cmdTable[cmd].cmd));
    if (HASIM(cmd)) {
    Serial.print(" b");
    printbin(im,4);
    } else {
    Serial.print(" ");
    }
    }

    void printop (uint8_t op) {
    uint8_t cmd = op >> 4;
    uint8_t im = op & 0x0F;

    Serial.print("b");
    printbin(cmd,4);
    Serial.print(" ");
    printbin(im,4);
    Serial.print("\t0x");
    printhex(op,2);
    }

    The main complexity is pulling the strings out of the command table. I’ve had to include a macro to provide access to the strings from the Arduino’s PROGMEM:

    #define FSH(x) ((const __FlashStringHelper *)x)

    This feels like a bit of a hack, but apparently this is how it should be done for the kind of thing I need to do!

    There is another macro here that needs explaining:

    #define HASIM(op) (op==0||op==3||op==5||op==7||op>9)

    This is a set of conditions that if true means that the command supports an immediate value. This is used in a few places to know how to parse the commands.

    Whilst in principle all commands could use the immediate value, the “official” statement of how they work assumes im=0 in many cases. So, for example, OUT B does not require an immediate value, but if one is provided then OUT B becomes OUT B+im.

    I’m not really supporting that with this code at the moment.

    Putting it all together

    Here is a serial output log of a session using the assembler.

    > H
    Help
    ----
    H: Help
    L: List
    G: Goto
    C: Clear
    R: Restore
    O: Opcodes
    OpCode
    OpCode im

    Current line: b0000 [0]

    > L
    RAM Disassembly

    b0000 [0]: JNC b1000b1110 10000xE8
    b0001 [1]: JMP b0011b1111 00110xF3
    b0010 [2]: OUT b0010b1010 00100xA2
    b0011 [3]: ADDB b0001b0101 00010x51
    b0100 [4]: OUT b0100b1010 01000xA4
    b0101 [5]: ADDA b0001b0000 00010x01
    b0110 [6]: OUT b1000b1010 10000xA8
    b0111 [7]: ADDB b0001b0101 00010x51
    b1000 [8]: OUT b0100b1010 01000xA4
    b1001 [9]: ADDA b0001b0000 00010x01
    b1010 [A]: OUT b0010b1010 00100xA2
    b1011 [B]: ADDB b0001b0101 00010x51
    b1100 [C]: JMP b0000b1111 00000xF0
    b1101 [D]: ADDA b0000b0000 00000x00
    b1110 [E]: ADDA b0000b0000 00000x00
    b1111 [F]: ADDA b0000b0000 00000x00
    Current line: b0010 [2]

    > G 13
    Goto line 13
    Current line: b1101 [D]

    > OUTB
    Assemble:
    b1101 [D] OUTB b1000 00000x80
    Current line: b1110 [E]

    > L
    RAM Disassembly

    b0000 [0]: JNC b1000b1110 10000xE8
    b0001 [1]: JMP b0011b1111 00110xF3
    b0010 [2]: OUT b0010b1010 00100xA2
    b0011 [3]: ADDB b0001b0101 00010x51
    b0100 [4]: OUT b0100b1010 01000xA4
    b0101 [5]: ADDA b0001b0000 00010x01
    b0110 [6]: OUT b1000b1010 10000xA8
    b0111 [7]: ADDB b0001b0101 00010x51
    b1000 [8]: OUT b0100b1010 01000xA4
    b1001 [9]: ADDA b0001b0000 00010x01
    b1010 [A]: OUT b0010b1010 00100xA2
    b1011 [B]: ADDB b0001b0101 00010x51
    b1100 [C]: JMP b0000b1111 00000xF0
    b1101 [D]: OUTB b1000 00000x80
    b1110 [E]: ADDA b0000b0000 00000x00
    b1111 [F]: ADDA b0000b0000 00000x00
    Current line: b1110 [E]

    > O
    Supported OpCodes:
    b0000 dataADDA im
    b0001 0000MOVAB
    b0010 0000INA
    b0011 dataMOVA im
    b0100 0000MOVBA
    b0101 dataADDB im
    b0110 0000INB
    b0111 dataMOVB im
    b1000 0000OUTB
    b1001 0000OUT2B
    b1010 dataOUT im
    b1011 dataOUT2 im
    b1100 dataJNCB im
    b1101 dataJMPB im
    b1110 dataJNC im
    b1111 dataJMP im

    > C
    Clearing RAM ... Done

    Find the code on GitHub here.

    Conclusion

    The basics for this actually came together fairly quickly, but I must admit to spending a fair bit of time fiddling about with output formats and refactoring various bits of code to try to give some consistency in terms of when newlines are applied, what is shown in binary, what in hex, and so on.

    I can’t guarantee everything has been caught, but I’ve typed in all the code (using the newer, limited syntax) from Part 3 and they all seem to work.

    It would be nice to be able to automatically reset the TD4 from the Arduino, but for now, pressing the button when required is fine.

    For the most part, unless there is a loop to get caught in, the code will cycle back to the start anyway.

    In terms of possible updates and enhancements, there are a few on my mind:

    • It would be nice to support the undocumented use of immediate values somehow.
    • It might be nice to have a way to save/load the code. It only needs to be a string of 16 2-byte hex codes.
    • It might be nice to have several demo programs to choose from.

    If I expand the instruction set and architecture, then I’ll have to think again about chunks of this code, but for now, it seems to work pretty well.

    Kevin

    #4bit #arduinoUno #define #td4

  17. TD4 4-bit DIY CPU – Part 6

    Having now successfully built my own version of the TD4 4-bit CPU in Part 5, I’m now chewing over some of the ways I’d like to try to expand it.

    • Part 1 – Introduction, Discussion and Analysis
    • Part 2 – Building and Hardware
    • Part 3 – Programming and Simple Programs
    • Part 4 – Some hardware enhancements
    • Part 5 – My own PCB version
    • Part 6 – Replacing the ROM with a microcontroller
    • Part 7 – Creating an Arduino “assembler” for the TD4
    • Part 8 – Extending the address space to 5-bits and an Arduino ROM PCB

    I already have a list of others extended projects at the end of Part 4, so I might be drawing on some of them for inspiration moving forward. Many of these are very similar projects, but with a completely different architecture. But really at this stage rather than build a different, more capable, 4-bit CPU from someone else’s design, I’m interested in seeing how far the TD4 design can go. So, ultimately, like all my projects, the fun here is in the reinventing and learning on the way.

    One of the questions I have is can I replace the DIP switches with something that can provide the data in a better way? This would be particularly critical if I expand the address space in the future. A ROM is the obvious option, but something more dynamic might be an interesting experiment too.

    This post looks at options for replacing the DIP switches with microcontrollers.

    Now I feel like I really ought to state right up front that this is a pretty ludicrous thing to do.

    At the more charitable end of the endeavor I’m using a 16MHz 8-bit AVR microcontroller with 2kB of RAM to serve up 16 8-bit values to a 10Hz 4-bit CPU.

    At the most extreme end I’m using a 125MHz, dual-core, 32-bit ARM Cortex M0+ CPU with 264 kB of RAM running an entire interpreted programming environment requiring (probably) millions of lines of low-level code to implement it, to do the same thing.

    So why bother? Well – why not?

    TD4 without the ROM

    To interface to a microcontroller, I’m after two things:

    • Ability to read the 4 address lines.
    • Ability to drive the 8 data lines.

    The best place to get at these signals is on the interface to the ROM itself – the 74HC540 octal line driver, and 74HC154 4-to-8 line decoder.

    Conveniently, these signals can be broken out quite easily on my board as shown below.

    The pink shaded area shows which components are needed for a ROM-less build. The two yellow highlights show where headers should be soldered to permit access to the address lines (top) and data lines (bottom).

    In this build, the following components are omitted from the full board:

    • 74HC154
    • 74HC540
    • 16x 8-way DIP switches
    • 128x small signal diodes
    • 8x 10k pull-up resistors

    I’ve used 6-way and 10-way pin header sockets to allow me to patch in a microcontroller. This allows for each header to conveniently include 5V and GND too. I’ve included the USB socket for power to the PCB but expect I’ll probably power the board via these 5V and GND links from the microcontroller.

    Using Arduino

    The natural choice here is to use one of the older Arduino boards, as these are all 5V IO which makes interfacing with the 4-bit CPU fairly straight forward.

    Using Arduino direct PORTIO should also make it pretty trivial to read address lines and write the data. I’ve configured the connections as follows:

    TD4 SignalArduino GPIOArduino PORTIOA0A0PORTC:0A1A1PORTC:1A2A2PORTC:2A3A3PORTC:3D0D8PORTB:0D1D9PORTB:1D2D10PORTB:2D3D11PORTB:3D4D4PORTD:4D5D5PORTD:5D6D6PORTD:6D7D7PORTD:7

    I’m avoiding D0/D1 (PORTD[0:1]) and D13 as they all have other hardware attached (serial port and LED in this case).

    Accessing the data corresponding to any specific address is as simple as follows:

    uint8_t ROM[16];

    loop:
    unt8_t addr = PINC & 0x0F
    PORTB = (PORTD & ~(0x0F)) | (ROM[addr] & 0x0F);
    PORTD = (PORTD & ~(0xF0)) | (ROM[addr] & 0xF0);

    The code could be simplified if I didn’t mind trashing whatever is configured for the other GPIO pins via the PORTIO, but it is good practice to preserve those values when only writing to a subset of the IO ports.

    In the final code below, I’ve included a toggle for A5 which allows me to do some timing measurements too.

    uint8_t ROM[16] = {
    0xB1, 0x01, 0xB2, 0x51,
    0xB4, 0x01, 0xB8, 0x51,
    0xB4, 0x01, 0xB2, 0x51,
    0xF0, 0x00, 0x00, 0x00
    };

    void setup() {
    DDRB |= 0x0F;
    DDRD |= 0xF0;
    DDRC |= 0x20;
    }

    int toggle;
    void loop() {
    if (toggle == 0) {
    toggle = 1;
    PORTC |= 0x20;
    } else {
    toggle = 0;
    PORTC &= ~(0x20);
    }

    uint8_t addr = PINC & 0x0F;
    PORTB = (PORTD & ~(0x0F)) | (ROM[addr] & 0x0F);
    PORTD = (PORTD & ~(0xF0)) | (ROM[addr] & 0xF0);
    }

    Running the code in a loop like this gives a scan frequency of around 500kHz and a response time of something like 2-3 uS for each read. That seems pretty responsive and I’m sure will be fine for a 10Hz CPU. And it is – it works great!

    Using Circuitpython

    One thing that would be really nice is a workflow that allows more of a “direct save to the CPU” approach to programming it. One option is to use a more modern microcontroller that supports a filesystem.

    The obvious choice here is a 32-bit microcontroller that supports Circuitpython. But will IO in Circuitpython be fast enough to respond to the CPU? There is one obvious way to find out – give it a try.

    There is another complication too – most Circuitpython boards run at 3.3V not 5V so that needs to be addressed too.

    Level Shifting

    I’m going to use a 74LVC245. The Adafruit product page puts it best:

    “essentially: connect VCC to your logic level you want to convert to (say 3.3V), Ground connects to Ground. Wire OE (output enable) to ground to enable the device and DIR (direction) to VCC. Then digital logic on the A pins up to 5V will appear on the B pins shifted down to the VCC logic.”

    This is an 8-way bi-directional bus transceiver and should be powered by 3V3, then the direction pin will determine the direction of the conversion as shown[ below.

    Two devices will be required. The address lines will need a 5V to 3V3 conversion; the data lines will need 3V3 o 5V.

    Here is how I’ve wired these up for a Raspberry Pi Pico:

    The Pico is connected as follows:

    • INPUT: GPIO 10-13 = A0-A3
    • OUTPUT: GPIO 2-9 = D7-D0 (not the ordering!)

    CircuitPython ROM

    The basic algorithm will be as follows:

    ROM = [16 command byte values]

    LOOP:
    Read four address lines
    Set data lines from ROM[address]

    For performance reasons it would be best to optimise both the reading of the address lines and the writing of the data lines, ideally into a single access. But as this is for a CPU that runs at a maximum of 10Hz, so for now, I’m just going with simple and see how it goes.

    import board
    import digitalio

    ROM = [
    0xB1, 0x01, 0xB2, 0x51,
    0xB4, 0x01, 0xB8, 0x51,
    0xB4, 0x01, 0xB2, 0x51,
    0xF0, 0x00, 0x00, 0x00
    ]

    Tpin = digitalio.DigitalInOut(board.GP21)
    Tpin.direction = digitalio.Direction.OUTPUT

    A0pin = digitalio.DigitalInOut(board.GP10)
    A1pin = digitalio.DigitalInOut(board.GP11)
    A2pin = digitalio.DigitalInOut(board.GP12)
    A3pin = digitalio.DigitalInOut(board.GP13)

    D0pin = digitalio.DigitalInOut(board.GP2)
    D0pin.direction = digitalio.Direction.OUTPUT
    D1pin = digitalio.DigitalInOut(board.GP3)
    D1pin.direction = digitalio.Direction.OUTPUT
    D2pin = digitalio.DigitalInOut(board.GP4)
    D2pin.direction = digitalio.Direction.OUTPUT
    D3pin = digitalio.DigitalInOut(board.GP5)
    D3pin.direction = digitalio.Direction.OUTPUT
    D4pin = digitalio.DigitalInOut(board.GP6)
    D4pin.direction = digitalio.Direction.OUTPUT
    D5pin = digitalio.DigitalInOut(board.GP7)
    D5pin.direction = digitalio.Direction.OUTPUT
    D6pin = digitalio.DigitalInOut(board.GP8)
    D6pin.direction = digitalio.Direction.OUTPUT
    D7pin = digitalio.DigitalInOut(board.GP9)
    D7pin.direction = digitalio.Direction.OUTPUT

    def doOutput (data):
    if (data & 0x01):
    D0pin.value = True
    else:
    D0pin.value = False

    if (data & 0x02):
    D1pin.value = True
    else:
    D1pin.value = False

    if (data & 0x04):
    D2pin.value = True
    else:
    D2pin.value = False

    if (data & 0x08):
    D3pin.value = True
    else:
    D3pin.value = False

    if (data & 0x10):
    D4pin.value = True
    else:
    D4pin.value = False

    if (data & 0x20):
    D5pin.value = True
    else:
    D5pin.value = False

    if (data & 0x40):
    D6pin.value = True
    else:
    D6pin.value = False

    if (data & 0x80):
    D7pin.value = True
    else:
    D7pin.value = False

    while True:
    Tpin.value = True
    addr = 0
    if (A0pin.value == True):
    addr = addr + 1
    if (A1pin.value == True):
    addr = addr + 2
    if (A2pin.value == True):
    addr = addr + 4
    if (A3pin.value == True):
    addr = addr + 8

    Tpin.value = False
    doOutput(ROM[addr])

    I’ve included a timing pin to GPIO21 so I can see how long it takes to access the IO.

    It turns out that it takes something of the order of 50-60uS to read the four address lines and something in the region of 70-80uS to write out the 8 data lines. The above simple Circuitpython code to do this is running with a frequency of around 7kHz.

    Now at this point I ought to be reading through the datasheets for the ICs used in the CPU to check response times and timing tolerances so see if this is ok. But I didn’t bother with any of that as it all appears to work!

    Conclusion

    The Circuitpython is obviously a lot slower than the Arduino running optimised PORTIO code, even though the Circuitpython is running on a 125MHz processor compared to the Arduino’s 16MHz. Of course, if performance was critical then switching to direct GPIO access in C on the Pico would be a lot faster again. Even just having a way to do a single block-access of GPIO would probably make quite a difference.

    But for this application, either as they are seem to work absolutely fine.

    The ability to quickly edit the ROM contents is pretty useful with the Circuitpython. But I am now wondering how difficult it would be to have some kind of uploader to the Arduino over the serial port. There are only 16 bytes to transfer after all.

    In fact it might even be possible to create a simple interactive assembler that allows code to be typed in over the serial port using proper word-based op-codes (like ADD, IN, OUT, etc). At the very least a simple serial port interface to type in numeric values would be relatively straight forward I think. It might also be possible to allow the microcontroller to reset the CPU too.

    I’m not sure the added complications of logic shifting, etc, make it worth carrying on with a Pico version at this stage, so I think improving the Arduino is probably the way to go for now.

    Kevin

    #4bit #arduinoUno #circuitpython #PORTIO #raspberryPiPico #TD4

  18. Gestern beim SFD Tech Treff:
    Analysiere UART Signal beim Midland M-5 CB Funkgerät zwischen Handmike mit Display und Funkgerät.
    0xFE 0x03 0x02 0x09 0x09 ^^

    Ziel: Neues CB Gateway :)

    #cbradio #logicanalyzer #hacking #segfaultdragons #electronics

  19. Ok, I just found out that when you print stuff, lldb doesn't actually print things properly.
    ```
    (lldb) run
    [...]
    -> 10 struct a a = (struct a){};
    [...]
    Target 0: (t) stopped.
    (lldb) print &a
    (a *) 0x000000016fdff1b8
    (lldb) print ((a *) 0x000000016fdff1b8)->a
    error: <user expression 1>:1:6: expected expression
    ((a *) 0x000000016fdff1b8)->a
    ^
    (lldb) print ((struct a *) 0x000000016fdff1b8)->a
    (int) 4266848
    ```

    I also just realized that lldb doesn't keep a history of values printed.

    #lldb

  20. (continued)
    How I found the Game Genie codes using FCEUX:
    1) By looking at the CHR ROM, I knew I wanted to use tile 0xd2 instead of 0x0a and 0xd7 instead of 0x0e.
    2) I looked at RAM in Hex Editor. A copy of sprite data was at 0x0700-0x07ff. The cursor was in the 2nd sprite slot, so the tile was at 0x0705.
    3) I set a breakpoint on 0x0705 write in Debugger. It found STA $0701,X. The previous instruction was LDA ($00),Y. Whenever that was run, RAM 0x00 contained 0x98 or 0x9d, RAM 0x01 contained 0xd8 and Y was 1, so a byte was being copied to A from RAM 0xd899 or 0xd89e.
    4) Indeed, during gameplay, CPU address 0xd899 contained 0x0a and 0xd89e contained 0x0e.
    5) I used nesdev.org/nesgg.txt to create the codes:
    - XSOSOEZA = "if the CPU tries to read a PRG ROM address that's currently mapped to CPU 0xd899 and contains 0x0a, return 0xd2 instead".
    - NSOSVETA = same but 0xd89e, 0x0e and 0xd7, respectively.
    #NES #gameHacking #GameGenie

  21. (continued)
    How I found the Game Genie codes using FCEUX:
    1) By looking at the CHR ROM, I knew I wanted to use tile 0xd2 instead of 0x0a and 0xd7 instead of 0x0e.
    2) I looked at RAM in Hex Editor. A copy of sprite data was at 0x0700-0x07ff. The cursor was in the 2nd sprite slot, so the tile was at 0x0705.
    3) I set a breakpoint on 0x0705 write in Debugger. It found STA $0701,X. The previous instruction was LDA ($00),Y. Whenever that was run, RAM 0x00 contained 0x98 or 0x9d, RAM 0x01 contained 0xd8 and Y was 1, so a byte was being copied to A from RAM 0xd899 or 0xd89e.
    4) Indeed, during gameplay, CPU address 0xd899 contained 0x0a and 0xd89e contained 0x0e.
    5) I used nesdev.org/nesgg.txt to create the codes:
    - XSOSOEZA = "if the CPU tries to read a PRG ROM address that's currently mapped to CPU 0xd899 and contains 0x0a, return 0xd2 instead".
    - NSOSVETA = same but 0xd89e, 0x0e and 0xd7, respectively.
    #NES #gameHacking #GameGenie

  22. In the NES game Yoshi's Cookie, you may be bothered by the cursor obscuring the cookies (top row in the screenshots). However, you can replace the cursor in one of two ways:
    1) Edit the iNES ROM with a hex editor to replace the cursor tiles with a blinking square in CHR ROM (middle row in the screenshots):
    - 0xff818181818181ff0000000000000000 to 0x200b0-0x200bf
    - 0x0000000000000000ff818181818181ff to 0x200f0-0x200ff
    2) Or, use these Game Genie codes to replace the cursor sprites with sprites that look like hands (bottom row in the screenshots): XSOSOEZA + NSOSVETA
    (continued)
    #NES #YoshisCookie #gameHacking #GameGenie

  23. In the NES game Yoshi's Cookie, you may be bothered by the cursor obscuring the cookies (top row in the screenshots). However, you can replace the cursor in one of two ways:
    1) Edit the iNES ROM with a hex editor to replace the cursor tiles with a blinking square in CHR ROM (middle row in the screenshots):
    - 0xff818181818181ff0000000000000000 to 0x200b0-0x200bf
    - 0x0000000000000000ff818181818181ff to 0x200f0-0x200ff
    2) Or, use these Game Genie codes to replace the cursor sprites with sprites that look like hands (bottom row in the screenshots): XSOSOEZA + NSOSVETA
    (continued)
    #NES #YoshisCookie #gameHacking #GameGenie

  24. @thgie @compudanzas there shouldn't be any magic at all! Labels just remember, locations in uxn's memory. Runes will just push the byte or short of that address.

    To check the stack state, you can press F2, or use #01 #0e DEO, in your program.

    wiki.xxiivv.com/site/varvara.h

    Sending a non-null byte to the 0x0e port will print the system's status, sending a non-null byte to the 0x0f port will terminate the application.

    #0e
  25. Es ist soweit!!
    Die Aufnahme der #episode 100 des #zeroday #podcast ist #online.
    Zum 6 jährigen die 100.
    Wer hätte das gedacht?

    100 folgen voller #datenschutz, #informationssicherheit, #tools, #wissen, #lernen, #technik aber auch extrem viel #spaß, #freude, #lachen, #lakritz und so viel mehr...

    Es ist für mich noch immer ein wenig #surreal, obwohl ich bei der #Aufnahme höchstpersönlich das #Audiorouting kaputt gemacht habe.

    Aber hört selbst:

    0x0d.de/2022/12/0d100-party/