Sunday, 5 October 2025

The Wonderful 74HC74

Put your Flip Flops on, let's go for a deep dive.

The 74HC74 (or 74LS74 or 74HCT 74 etc.) is a commonly used part in my designs and many others.

I thought it would be interesting to have a bit of a run through some of the many and varied uses of such a useful chip.

It is a dual D-Type Flip Flop. With two halves, each of which can be

  • A clocked latch
  • A set / reset latch
  • A flip / flip

And various combinations of the above.

It is the combinations which make it such a simple and yet powerful building block.

It was one of these combinations which sparked this piece. I had a great idea at 3AM one morning, but wasn't sure if it would work, and it required a bit of thinking through and tweaking the design to get there.

I thought it might be interesting to go through some of the many and varied uses of the 74HC74 in my designs.

So what is it?

The 7400 series was introduced in the mix 1960s, with the 74LS in the early 1970s and 74HC in the early 1980s.

It blows my mind in a world where technology changes so quickly that essentially the same parts have been in production for nearly 70 years. (yes, I know those are 175s, and yes I know HC isn't the same as LS, that was just the ones I happened to have a picture of)

This 74LS74 dated 1977 is in my Commodore PET 2001.

That's a Motorola version, this was the earliest Texas Instruments one I could find on any of my boards, first week 1980.

Here is one from 2020 (if I read the date code correctly) on a Minstrel 2.

The pinout

The first flip flop uses pins 1-6, the second pins 8-13, with the power on the corners as was usual for 74 series TTL chips (apart from a few oddballs, including the early 5474)

My PCB software lets my draw my own symbols, so these are the ones I use for the 74. I add the symbol to the side of the clock to remind me it operates on the rising edge.

Each half has 4 inputs and 2 outputs, for the moment, lets look at just three of them.

Clock

The clock input is an edge triggered input, things happen on the positive rising edge of the clock signal. Most of these chips seem to be clocked on the positive rising edge.

Data

When that edge happens, it samples the D or data input and copies it to the Q output.

Simple as that.

Q

Q only changes at the point the clock input changes from 0 to 1 (or a few tens of nanoseconds after).

This is useful for things like output ports on 8-bit microprocessor systems. These usually have a timing diagram something like this.

The address and function signals (read / write, memory or IO, etc.) are set usually on one part of the processor clock cycle (not to be confused with the clock on the 74). The data is then setup in the next part, although these are only valid for the later parts of the cycle, specifically at the point where the CPU clock changes.

The decoding logic for an IO port is usually setup so the port is active when the address is matched, so will go low towards the end of the first half of the CPU clock cycle, depending on how long it takes the propagate through the decoding logic.

Most of these circuits do not reference the processor clock itself, but are based on the address changing at the start of the next processor clock cycle. As soon as the address changes, the decoding logic will cause the clock pin of the latch to go back high, and at that point, the 74 will sample the databus and copy that level on the D pin to the output Q pin.

An example of this is the save output on the Minstrel 4th. This latches the value on the D3 bit of the databus when port $FE is written to. The Q output is used to drive the microphone input of the cassette recorder.

The clocked latch can also be useful for cleaning up signals, for example the video output on the Mini PETs and Minstrels and similar computers.

These have a video output which is a combination of the output of a shift register and a separate invert signal. These allow you to get twice as many characters by creating inverted versions of the ones you already have without having to store those in ROM (or RAM).

A problem seen on the output of the ZX80 and PET 2001 on modern monitors are shadow lines at the edge of some characters, caused by the invert signal changing at a slight different time to the character data. So for a brief moment, the invert signal is still set for the previous character, but the shift register output has changed to the next character.

The flip flop can be used here to use the 6.5MHz clock edges to sample the video data signal once per character, so the output can only change once per pixel, so you get a nice neat output with no glitches.

For the PET 2001 version, I fixed that with a single gate 74 surface mount chip mounted in a board which plugs into the socket of the 74LS08 it was driving. (OK, it's called a 74LCV1G175, but it operates just like a single 74 gate)

Frequency divider

Another common use for a flip flop is as a frequency divider. Here we need to bring in another pin

/Q or Q bar

There isn't a neat "Q with a line over it" symbol I can put in the text, so I use /Q. This is simply the inverted version of Q, and is set at the same time, a complimentary pair.

If you wire the /Q output to the D input, then on each rising edge of the clock, Q will be set to the value of the previous /Q output, which is the inverse of the previous value of the Q output, so it toggles.

This can be used to generate exactly half the frequency of the clock input, here generating 3.25MHz from a 6.5MHz input.

It is also a very clean 50:50 mark:space square wave, even if the input is very asymmetric, as the output is toggling on the rising edge, so does not care when the falling edge occurs.

The same sort of thing can also be used for a toggle function. Press a button to turn something on, press it again to turn it off.

The clock in this case is a debounced signal from a push switch.

Here pressing it once sets the /Normal output high and /Turbo low, press again and they change, /Turbo goes low and /Normal goes high and so on.

This circuit also uses the two other pins.

/CLR and /PRE

The remaining two inputs are clear and preset. Unlike the clock, these are level triggered. They normally sit at logic 1, and are active when the input is logic 0.

/CLR or clear is used to clear the output of the flip flop, so any time that pin is 0, the Q output will be fixed at 0, and /Q at 1, no matter what the clock and data inputs are doing, and will stay low until the next clock pulse (or /PRE goes low)

/PRE or preset works in the same way, but presets the Q output to a 1 and /Q to a 0, and again those will stay like that all the time /PRE is low.

In the above circuit, they are used so the microcontroller can force the flip flop into one mode or the other.

It is undefined what happens if both /CLR and /PRE are low, don't do that, it may cause the universe to implode.

/CLR is quite useful to wire to the system /RESET, so that the flip flop will always start in a known state.

For example, the mic output on the Minstrel 4th could have used /CLR to force the output low after reset, but the original Jupiter Ace version didn't, so I didn't.

Shift Register

Another thing you can use a 74 for is to create a shift register. Here in the Minstrel 3 video circuit, I only needed a couple of stages, but by tying the clock inputs together and chaining Q (or /Q) to the next D, you can create a shift register which propagates a signal down the line on each clock pulse.

That is used to generate the back porch signal for the video on the Minstrel 3, driving the /CLR input as sown above to force the video output to be low for the screen borders.

The Minstrel 2 version is a bit more analogue.

The CLR input on the flip flop is driven from an RC circuit which extends the sync pulse to create a back porch for the video signal to set the black level before the white borders start.

That circuit also contains an unusual use of the 74. I needed to buffer the sync signal, but I did not have any spare gates, only half of a 74 flip flop.

I had Sync and /Sync signals, so I was able to use the 74 to recreate a version of Sync by driving the /CLR and /PRE inputs.

That was one of those times where I had to work it through all the possibilities to see if it was OK, as I had not seen it done before.

I've had a great idea....

That brings me to the idea I had a few days ago.

The Minstrel 4th can run at 3.25MHz or 6.5MHz, and this is currently selected by a pair of jumpers.

This isn't an ideal solution as I am sure someone will have tried fitting both jumpers to see if they get 9.75MHz (you don't).

The 6.5MHz used for the video circuitry is buffered by a spare 74HC86 gate and then divided down to get the 3.25MHz clock.

On the Minstrel 4D, there was quite a complicated circuit to select Trubo™ mode (on the first prototype, I managed to spell Turbo wrong, so I still call it Trubo mode).

Here the buffered clock is divided down, and the other half of the flip flop selects which clock is passed through to the output.

The OR gates here only pass through the clock when the control input is low. When /Normal or /Turbo are high, the output of their respective OR gates is always logic 1.

(There, fixed, I don't think anyone noticed)

There isn't space for all of the turbo button circuitry on the Minstrel 4th, so I was trying to think of a way of doing that with a single jumper, but without adding any parts, a 74HC257 would have done the job, but I don't want to add a whole extra chip just for that, likewise the OR / AND mixer circuit above.

I wondered if I could make the half 74HC74 that I had into some sort of configurable divider, to produce 6.5MHz or 3.25MHz.

As it currently works, on every rising edge of the 6.5MHz clock, the /Q output is copied to the Q output, so toggling it.

This gives an output which is half the frequency of the input, so we get the 3.25MHz output.

I was wondering if I could use the /CLR input to set Q low half way though the cycle and then it would always be set high again at the start of the next cycle, maintaining the 6.5MHz output.

I would use a jumper to select if /CLR should be high (for 3.25MHz) or be a short pulse on the falling edge of the 6.5MHz clock (for 6.5MHz).

My first attempt used an RC circuit.

I tried lots of values for the R and C, but I couldn't quite get the short pulse I wanted, although it did appear to work.

I wasn't happy that would be reliable, I need the /CLR signal to be safely high before CLK changes. If the /CLR signal does not rise before the CLK, then it will ignore the clock signal and the output will stay low. At half time, /CLR will force the low output to continue to be low and so on, not changing.

After some pondering, I came up with a plan B, which is to use the spare XOR gate to delay the 6.5MHz clock. The propagation delay of a 74HC86 is 10-20ns, which doesn't sound much of a delay, but consider the period of the 6.5MHz clock is only about 150ns.

The logic analyser is only measuring to 5ns, so that is only two samples.

But that is enough to make it work.

The delayed clock pulse means /CLR will not be active when the Clock rises, so it will always clock in high and at (about) half time, will be forced low.

That allows the single jumper to select 3.25MHz or 6.5MHz.

That all seems to be working nicely, so I will add that to the next revision of the board.

Other notable mentions

I should also give a mention to some of the similar chips, the 175 is a quad version which has a common clock and clear (/MR, master reset), but still has Q and /Q outputs.

The 174 is a hex version, again with common clock and clear, but does not have the /Q outputs

The 273 is an octal version.

The 374 is similar but has an output enable in place of the clear.

And finally, the 574 which is the same as the 374 but with the pins arranged in a more pleasing order.

Conclusion

All in all, a very useful chip that can be used in all sorts of ways. Have I missed out any other ways you can use a 74?

This was a bit out of the ordinary, but I hope you found it interesting.

Would you like to see more like that, following some discussions on the discord, a post on the 555 timer might be interesting?


Adverts

The Minstrel 4th is available form my Tindie store:

I can still ship worldwide and US orders are now tariffs paid.

Currently it looks like Royal Mail to the US is working, and I pay the 10% tariffs as part of the postage to (hopefully) avoid delays and additional costs that customs. The increased postage costs cover this.

I have also built some more Mini PET 40/80 Internal boards, since the Mini PET II is still in development but people keep asking, so here they are.



Patreon

You can support me via Patreon, and get access to advance previews of development logs on new projects like the Mini PET II and Mini VIC and other behind the scenes updates. This also includes access to my Patreon only Discord server for even more regular updates.

Sunday, 28 September 2025

Revisiting the Minstrel 4th Enhanced Forth ROM

When I relaunched the Minstrel 4th earlier this year, I added some more ROMs to the standard ROM image. These included the ZX80 and ZX81 BASIC I have talked much about, and the Enhanced Forth ROM which I have not.

This is the work of Alexander Sharikhin, and features additional code by George Beckett (and I think the clock check and BEEP patch might have been by me? or maybe just "Based on an original idea by Tony Warren Dave Curran")

This takes advantage of the extra 5K of ROM space I gave the Minstrel 4th, and adds various new functionality to the Forth ROM, including:

  • Serial communications using the 68B50 RC2014 module
  • LOAD and SAVE via serial using server program at PC end
  • LOAD and SAVE blocks of memory using XMODEM
  • Serial => Keyboard input and Screen => Serial
  • Programming tools to support hex characters and code blocks
  • CASE statements
  • BEEP patched to adjust frequency when run at 6.5MHz

When I came to add that, even though the latest source was 5 years old, I appeared to have an older version, so I though it best to get the latest version and tried to build it.

That didn't go well. It needed the sjasmplus compiler with LUA support, and I couldn't get that working. Not sure what I was doing wrong. I guess something in current version of LUA or sjasmplus has changed to make it incompatible with the other.

At the time, I took the easy option of asking George to build it for me, and that was the version that went into the ROM.

I have been planning to revisit that for a while, I wanted to achieve a few things:

  • Be able to built it (quite important)
  • Add new functionality
  • Integrate the ACE ROM source
  • Rename some words

The current version is a patch. It takes the compiled Jupiter ACE ROM binary and patches a few things in there to graft in the new commands, which are compiled and added onto the end. 

It also patches the names of LOAD, SAVE, BLOAD and BSAVE to change those to LOAT, SAVT, BLOAT and BSAVT to allow the new routines to use the standard names (the change of letter so not to change the code size, hence why it wasn't changed to TLOAD for example)

I can see why that has been done, but I think I would prefer to leave the standard tape load as LOAD and make the serial load SLOAD (or ULOAD to match things like UINIT which initialises the UART).

That way, I think I would push this as the main ROM, with the option of going to the original unmodified version if you want. A normal user could just run LOAD as normal for a tape load without being aware of the new functionality.

It would be ideal if I could have all the source together in a single place and do one build command to build the whole ROM from source. That is non-trivial, since the ACE source I have is based on Geoff Wearmouth's commented disassembly, and that is written to use the TASM assembler.

That's fine by me as I have been using TASM to write Z80 code since I got a copy on 5¼" floppy from a teacher at school. All of the ZX80 and ZX81 BASIC etc. is written in TASM so it seemed the best bet to stick with that.

All I had to do was manually apply the patches to the Ace source and merge the source together.

Easy.

End of post, take the rest of the day off.

Ah, no. Not quite.

It turns out there are quite a few differences between TASM Z80 and sjasmplus. Many of them were just search and replace, but some required a bit more thought.

Here are some examples I found.

Numbers

The numbers were in several formats, 0x1234 and also #1234 (which I found rather annoyingly Visual Studio Code displayed with a box to the left showing what #1234 would look like if it were an HTML colour).

I am sure there is a way to turn that off, but I need to change them anyway since TASM used $1234 for hexadecimal numbers (and also 1234H, but I rarely use that notation).

RECV_RETRY: equ 0x1000  🠆  RECV_RETRY .EQU $1000

TMP_DICT = #2709  🠆  TMP_DICT .EQU $2709

That was mostly search and replace, but as with all of these changes, a good opportunity to read through the code and find out what it all did (and for me to unnecessarily align all the comments because that's the way I roll).

Local Labels

Local labels save you having to think of a new name for the point you jump back to in a loop every time.

You can't call them all "loop", so you can use a local label that's just called "loop" within this scope of your function. sjasmplus uses ".loop" for this, but TASM uses "_loop" (you can change that, but I'd rather stick with the standard). That's not too bad, just search and replace again.

But the scope is also different. In sjasmplus this seems to be relative to the last proper label only.

main:

    ld b, 42

.loop

    djnz .loop

That .loop is treated as main.loop, which makes sense and is a neat way to do it.

I use ACME for 6502 code, and that also has + and -, so you can do

main:

    lda, 42

-   dec

    bne -

Where - just refers to the previous - label, and + to the next + label (you can do -- and ++ as well for the one before / after that, but it starts to get a bit complicated and is usually better to give things names unless it's obvious)

TASM doesn't have either of those, it needed .MODULE definitions adding where necessary to control the scope.

main:

          .MODULE MAIN       

    ld b, 42

_loop

    djnz _loop

So that is now MAIN._loop.

Instruction differences

There were a few instructions that had to be changed.

ex hl, de

That was used in a couple of places. This isn't an "official" Z80 opcode, but the assembler just accepted it and converted it to the more correct

ex de, hl

TASM didn't, so I had to do that manually.

I wanted to check that to be sure, so I disassembled the Enhanced part of the ROM.

z80dasm -a -g 0x2800 -l -t 2800.bin

That gave me a listing of the code so I could check what had actually been built.

ex de,hl

Yes, the compiler had just replaced the instruction.

The next one confused me, as far as I know, there isn't an ld (hl), de instruction.

.save:

ld (hl), de

ret

Checking the disassembly, it turns out the code actually generated was:

ld (hl),e

inc hl

ld (hl),d

dec hl

ret

Interesting, not sure why you would use an instruction that doesn't exist, particularly if for example, you didn't need the value in hl, so the last dec hl would be unnecessary.

_save:

   ld (hl),e                ;ld (hl), de

inc hl                     ;

ld (hl),d                  ;

dec hl                     ;

ret

I left the original instruction in the comment for reference.

This one also confused me.

dup 4

call loadVar

jr c, _error

edup

I was thinking this was some kind of forth thing, since dup is a forth word to duplicate the item at the top of the stack

But no, it must be a compiler thing. Looking at the disassembly it appears to mean "duplicate this 4 times......end duplicate"

   call sub_2ac6h

jr c,l2ce0h

call sub_2ac6h

jr c,l2ce0h

call sub_2ac6h

jr c,l2ce0h

call sub_2ac6h

jr c,l2ce0h

I just replace that with the unrolled code, again with a comment

RST calls

There were two variations of RST calls, using 0xnn and #nn (both seen in this function)

.cont:

rst 0x08 ; Print character

pop bc

djnz .loop

ld a, CR

rst #08

ld a, e ; Retrieve block type

and a ; Indicate success

ret

Unfortunately it turns out TASM doesn't accept either of those. Furthermore, it doesn't accept what I would have expected

    rst $08

You have to do

    rst 08H

More search and replace and we are getting closer.

Just a side note, got to love Z80 syntax

    cpl  ; Compute 255-A, ones ComPLiment

    cp l ; Compare A to the L register

And

    rra  ; Rotate accumulator right through carry (4 cycles)

    rr a ; Rotate accumulator right through carry (8 cycles)

Oh, for a RISC processor ......

Forth Words

The elephant in the room.

The is probably described better somewhere else, by someone who understands it better that I do, but here goes.

The forth dictionary is a singly linked list. There are two bytes at the end of the original ROM at $1FFD. This points to the first word in the dictionary (after FORTH).

On the original ROM that is UFLOAT, but if you wanted to add a new word into the ROM, you would change the value at $1FFD to point to your new word, and you would set your word to point back to UFLOAT, inserting it into the chain.

(what, you didn't expect me to include a vlist print out? at least I might have surprised you by not using the inverse colour scheme I normally do)

There are lots of forth words added in the enhanced ROM, all of which are linked between FORTH and UFLOAT.

(paused part way through as they normally scroll off the top of the screen - do we need a new vlist word with a ZX Spectrum style SCROLL? function????)

(a benefit of the work I previously did getting the extra 5K supported in EightyOne means I can now run and debug the enhanced ROMs. Not perfect as the save detection has to be disabled to avoid false triggering with the ZX ROMs)

In the original ROM, forth words are defined as follows:

; ---------------

; THE 'BASE' WORD

; ---------------

; ( -- 15423)

; A one-byte variable containing the system number base.

; $3C3F BASE

L0483:  DEFM    "BAS"                   ; 'name field'

        DEFB    'E' + $80

        DEFW    L047F                   ; 'link field'

L0489:  DEFB    $04                     ; 'name length field'

L048A:  DEFW    L044D                   ; 'code field'

The actual code follows elsewhere, pointed to by the code field.

The name is "BASE", the last letter of which has $80 added to it to indicate the end of the string.

There is also a length field, which in some cases has $40 added to indicate an immediate word (for things like DO WHILE, IF THEN ELSE etc.)

The links are all hard coded, from word to word, in the order they appear in the file (not sure if that is true for all of them, but it seems to be the general case).

This was one of the nice features that the enhanced ROM needed sjasmplus assembler with LUA for.

w_uinit:

FORTH_WORD "UINIT"

call uart_init

jp (iy)

.word_end:

FORTH_WORD is a macro which expands out to the type of header above, creating the name, link and length fields automatically.

I couldn't use that, so I had to do it manually, in the same way as the original ROM (or at least the disassembly - maybe they had some equivalent function in whatever assembler was used for the Ace ROM).

w_uinit:

;FORTH_WORD "UINIT"

    .MODULE UINIT

    .BYTE "UINI"            ; 'name field'

    .BYTE 'T'+$80           ;

    .WORD w_uread_link      ; 'link field'

w_uinit_link:    

    .BYTE $05               ; 'name length field'

    .WORD w_uinit_code      ; 'code field'

w_uinit_code:    

call uart_init

jp (iy)

I initially hard coded all the links, setting the link address to the label for the previous word (in this case UREAD), and then setting a new link label for the next word to use.

Right, almost there.

CASE

The last thing to tackle was the code for the case statement construct. This was in a different format to the standard assembly code words. This one used FORTH words (or bits of them), in the same way as a few original words, such as ROT. This rotates the top three bytes of the stack:

; --------------

; THE 'ROT' WORD

; --------------

; (n1, n2, n3 -- n2, n3, n1)


L08F9:  DEFM    "RO"                    ; 'name field'

        DEFB    'T' + $80

        DEFW    L08ED                   ; 'link field'

L08FE:  DEFB    $03                     ; 'name length field'

L08FF:  DEFW    L0EC3                   ; 'code field' - docolon

; ---

L0901:  DEFW    L08D2                   ; >R

L0903:  DEFW    L0885                   ; swap

L0905:  DEFW    L08DF                   ; R>

L0907:  DEFW    L0885                   ; swap

L0909:  DEFW    L04B6                   ; exit

It does that using five forth words, rather than any assembly language.

It appears CASE and related words are the same, but the version in the source is just a list of bytes.

;; CASE

ABYTEC 0 "CASE"

dw LINK

SET_VAR LINK, $

db 0x44

db 0x08, 0x11

dw $ + 0x0f ; 0x93, 0x3C

db 0x11, 0x10, 0x00, 0x00, 0x11, 0x10, 0x09, 0x00

db 0x40, 0x11, 0x00, 0xE7, 0xFF

db 0x42, 0x11, 0x79, 0x08, 0xB6, 0x04

To get building, I just pasted in the bytes from the disassembly (code and header).

;; CASE

.BYTE $4F, $C6, $69, $29

.BYTE $42, $08, $11, $A1, $29, $11, $10, $09, $00

.BYTE $46, $29, $60, $04, $11, $10, $00, $00, $4E

.BYTE $0F, $11, $10, $07, $00, $40, $11, $02, $DF

.BYTE $FF, $42, $11, $D2, $08, $12, $09, $4A, $0C

.BYTE $DF, $08, $85, $08, $83, $12, $09, $00, $79

.BYTE $08, $79, $08, $71, $12, $0B, $00, $B3, $08

.BYTE $DF, $08, $D2, $0D, $D2, $08, $A4, $12, $B6

.BYTE $04

OK I think it's there, so time to build it.

wine TASM.EXE -80 -b -L minstrel4th.asm minstrel4th.rom

I am on linux, but still using the old DOS command line TASM, via wine.

I had a few typos to fix here and there, but finally got it built.

I use HxD hex editor (again because I have been using that since the year dot), and that brought up a few differences, usually cut and paste errors with links in the word definitions.

A few more tweaks and I finally got it to build binary identical.

Great.

End of post, take the rest of the day off.

Ah, no. Not quite.

The challenge now was to fix the links, and do something with the case code.

Automatic linked list

The FORTH_WORD macro used a variable called LINK, which was initialised to the address of UFLOAT (first word after FORTH in the original ROM). This was then updated each time to the current link.

Once I worked out the syntax for TASM, I was able to use the same sort of thing, so I went through and replaced all the hard coded links with this new automated link code. E.g.

w_hex:

    .TEXT "HE"              ; 'name field'

    .BYTE 'X'+$80           ;

    .WORD LINK            ; 'link field'

LINK .SET $ ;   

    .BYTE $03               ; 'name length field'

    .WORD w_hex_code        ; 'code field'

w_hex_code: 

ld (IX + $3F), $10

jp (iy)

That was neater and will also allow me to change things more easily.

I rebuilt it and it was still binary identical. Great.

Making the case

I now had various different sources for case the version in the enhanced ROM with a header and just bytes. The version from the disassembly that was just bytes.

I now had found a third, from Geroge's github

https://github.com/markgbeckett/jupiter_ace/tree/master/case

This was in the form of the forth words.

0 COMPILER CASE

  0 ( MARKER ON STACK, USED BY ENDCASE TO CHECK DONE )

  9 ( SYNTAX GUIDE, MUST MATCH WITH 'OF' )

RUNS>

  DROP ( NOTHING TO DO EXCEPT DROP ADDR OF PARAMETER FIELD )

;

With a bit of searching through the various versions, I was able to create something a bit more readable than the list of bytes (but still binary identical)

.TEXT "CAS" ; 'name field'

.BYTE 'E' + $80

.WORD LINK            ; 'link field'

LINK .SET $ ;

.BYTE $04 + $40 ; 'name length field' (immediate word)

.WORD L1108 ; 'code field' - compile

.WORD w_case    ;

.WORD L1011 ; stack next word

.WORD $0000 ; 0

.WORD L1011 ; stack next word

.WORD $0009 ; 9

.WORD L1140 ; (part of) RUNS>

.BYTE $00, $E7, $FF ; ???

w_case:

.WORD L1142 ; (part of) RUNS>

.WORD L0879     ; DROP

.WORD L04B6 ; exit

I think I understand most of that, although I am not sure about the code that makes up the "RUNS>" bit.

The important thing is that it still builds binary identical, and I do not think there are any absolute links, so the code could move around and still build and work.

What next?

I have a few things to add in terms of functionality and also hardware support. If you think of anything else that would be useful, there is still about 2.5KB remaining.

I am also thinking about spiting up the source further into separate files for each word, grouped in folders, rather than all the related words in a single file etc. Not sure if that is necessary or beneficial, but it might make reordering things a bit easier. I will try it for the new words, and if it works out, I will probably go back and reformat the existing code (I will go back to this version and make it build identical before I add back the new code).

I also hope none of that comes off as critical or negative, that wasn't my intention, this was just my choice to give myself a lot of work translating someone else's code to an archaic assembler that I happen to like, to theoretically make my life easier in future.


Adverts

The Minstrel 4th is available form my Tindie store:

I can still ship worldwide.

Currently it looks like Royal Mail to the US is working although it seems I now have to pay the 10% tariff, so hopefully that will be plain sailing and no problems with customs. We're all pawns in a petulant child's political games, but we've got to just keep going and try to make this stuff work.

I have also built some more Mini PET 40/80 Internal boards, since the Mini PET II is still in development but people keep asking, so here they are.



Patreon

You can support me via Patreon, and get access to advance previews of development logs on new projects like the Mini PET II and Mini VIC and other behind the scenes updates. This also includes access to my Patreon only Discord server for even more regular updates.