Dr. Jim's BASIC dumping ground

Show us what you're working on, (preferably with screenshots).
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Dr. Jim's BASIC dumping ground

Post by TMD2003 »

I figured that now I'm here, I may as well showcase (again, in some cases) what I've been up to when I've dug back into Spectrum programming and stuck with it long enough to see a project through to the end. What I'll put here is anything that won't be submitted to CSSCGC or the like - non-game programs I wrote, many of which will be something to do with maths, UDGs/character sets and PLAY commands, because I find that easy to program without getting well and truly stuck (like Sticky the stick insect on a sticky bun). Maybe it'll all get drowned here in a sea of machine code, and what I know about that can be written on a pinhead. Then again, magazine covertapes contained plenty along the lines of what I've done here, and I wouldn't mind betting I could have sent some of this to 16/48, Outlet or similar, had I been there at the time.

Anyway, I'll start with today's effort...

============================================================================

Image

Dr. Jim's Mighty Musical Character Sets

I'd been thinking of making another Crap Game - even though I have two in the pipeline that have been submitted for publication but haven't been revealed yet. Anyway, I was thinking of something musically-themed, and realised I would need some graphics for it. They've come out rather larger than I imagined - the treble clef is 3 x 8 character squares - so even though the two character sets together take up only 1.5K, the screen size will make the game somewhat limited (thus making it premium CSSCGC material).

There's a TZX in this package of the two character sets held separately as 768 byte files called "C1" and "C2", and another TZX of the two combined as one 1.5K file... with a 26.5K demonstration program that is a long, long, long listing of PRINT AT (...AT, AT, AT, AT, AT and AT again...) statements, with a sniff of PLOT and DRAW. Any BEEPs to accompany the notes will be minimal until the very end.

Provided amongst the graphics are:
- G, F and C clefs, which can be positioned at any line on the stave - everything is designed to fit around the stave being drawn as a series of symbol-shift-0 underlines.
- Crotchet and minim note heads, for notes on lines and in spaces, with instructions on how to convert PRINT AT coordinates into PLOT positions to draw the stems.
- Semibreves, for line and space (and it's not the same as a minim head) - note that the "modern" breve and longa can be derived from this with a few DRAW lines, but you'll have to figure those out yourself.
- Archaic long notes (breve, longa, maxima) for line and space, in the rectangular style, with PLOT positions for the longa and maxima stems.
- A dot! It always fits in the space. It could also be used for staccato, but will be slightly off-centre.
- Quaver crooks in all orientations, with extra fill-in characters that stack perfectly to make quaver fractions.
- Rests, everything from maxima to demisemiquaver - and again, the fractional quaver rests have stacking characters.
- Accidentials - sharp, flat, natural, double-sharp, for line and space.
- Time signatures - digits available are 1-9 and 12, and common time C. A quick PLOT and DRAW will turn the C into the alla breve symbol, but you'll have to work that one out yourself.

I could have gone on, adding more and more graphics into more and more character sets, but I figured this is enough for now. Character set "C3" would probably involve dynamic marks (if it's possible to define a single f, p and m and print them alongside each other to form ff, pp, mf etc.), segno, coda, fermata, trill, mordant, accent, a proper staccato dot... there's loads left. And if it ran to a "C4" character set, that might have weird things such as half-flat, half-sharp, sharp-and-a-half, that only really odd people who think they have more finely tuned ears than the rest of us plebs will ever deal with.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Dr. Jim's BASIC dumping ground

Post by R-Tape »

I'm one of the least musically minded people out there, but even I know that's a beautiful treble clef.

Please keep dumping—PM sent.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Dr. Jim's BASIC dumping ground

Post by Ast A. Moore »

R-Tape wrote: Sat Apr 18, 2020 10:13 pm I'm one of the least musically minded people out there, but even I know that's a beautiful treble clef.
Indeed. However, the bass clef looks a little undersized compared to it.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
R-Tape
Site Admin
Posts: 6353
Joined: Thu Nov 09, 2017 11:46 am

Re: Dr. Jim's BASIC dumping ground

Post by R-Tape »

Ast A. Moore wrote: Sat Apr 18, 2020 10:19 pm Indeed. However, the bass clef looks a little undersized compared to it.
R-Tape wrote: Sat Apr 18, 2020 10:13 pm I'm one of the least musically minded people out there, but even I know that's a beautiful treble clef.
Haannnng on. I mean quavers. I think. Beautiful quavers there :?
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Dr. Jim's BASIC dumping ground

Post by Ast A. Moore »

R-Tape wrote: Sat Apr 18, 2020 10:27 pm I mean quavers. I think. Beautiful quavers there :?
Damn amateurs and classical musicians and their fondness for calling eighth notes “quavers”! :evil: Can’t bloody tell a clef from a note . . .

:lol:

Yeah, I was confused whether you were joking or not, so I downloaded the demo, launched it and sure enough, the first thing I saw was this:

Image
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

To clear up any concerns:

What I did here was, I took screenshots of musical scores from Wikipedia initially - that's where the clefs came from - then found that a lot of their diagrams were hosted in tiny PNG files where the stave was smaller than it had to be on the Spectrum screen - i.e. that the distance between the lines was less than seven pixels. Ideally I needed the symbols to be as large as possible, so I opened MuseScore (which I'd recently downloaded as a more recent freeware equivalent of Noteworthy Composer, to check out some MIDI files) and played around with the various notes, rests and symbols available, with the zoom set at 800%. Print Screen, paste to GIMP, brightness down, contrast up, scale so that there would be seven pixels between the lines, drop to two colours, paste into an XCF file with a transparent 8x8 grid on one layer... and then start typing in the binary codes. Lots and lots of binary codes. A near-continuous soundtrack provided by Clutch and Iron Maiden may have helped here.

One thing is certain: everything is the correct scale relative to everything else, so if the bass clef looks small, look at it again with the stave superimposed, and then loot at a real musical score. It's absolutely bang on. The only tiny compromise I made was to shift the crotchet rest up one pixel so that it would fit into six squares; also, the 12 and 1 in the time signatures aren't exactly centred, but it allowed the 12 to fit into six squares and the leftmost squares to be re-used to make the 1. Then, the top right character of the 1 could be re-used to form 40% of the breve rest. It's unlikely anyone would ever notice these one-pixel shifts had I not pointed them out.

This post has generated rather more interest than I'd thought. Maybe I should get on with that Crap Game before someone steals my thunder! Though I've got those last few Sinclair User listings to type in, I can't let that drop now.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

R-Tape wrote: Sat Apr 18, 2020 10:13 pmPlease keep dumping.
Time for Dump Number Two (ooer, sounds a bit rude!): something I made in my last Spectrum-programming-frenzy that didn't last quite as long as I'd intended, but still made this. Presented as it was then... mostly.

INITIAL IMPORTANT NOTE BEFORE ANYONE ASKS ME: Although these were written on Spectaculator and just about everyone will only ever test them for two minutes on an emulator, they were written to be as easy as possible to use on a real Spectrum - right down to the original rubber-keys model which needed SYMBOL SHIFT for the decimal point and the simple mathematical functions. So I made the keypresses shift-free, i.e.:
To multiply 2.4 by 0.3 you'd need to press: 2, M, 4, ENTER (to put 2.4 on the stack), M, 3, B.

Were I to make a third "Spectrum Brain RPN calculator" I'd check for all the shifted keypresses (with either shift key), and probably run it though a compiler to see if that could make it any less slow. But I've got plenty more to be getting on with for now!

-------------------------------------------------------------------------
MARCH 2017...

I set myself a small challenge. Back in the mid-90s when I was still at school, my physics teacher, who was something of an Apple devotee (it was probably his decision that the school used Mac Plus, Classic and LC II models) as well as Hewlett-Packard RPN scientific calculators. He showed us how RPN worked and how it was different to the Casio and Sharp models we all had, and he showed us an RPN calculator program he'd written on an Apple IIe.

I could have done the same in my first enthusiastic stint here alongside the CCSCGC programs, but for whatever reason, it took until 2017 for me to get the idea that if my physics teacher of 20 years ago could write an RPN calculator program, why couldn't I? Why had I never tried to do it before?

So I did.

Image

Download link: http://www.rickdangerous.co.uk/hammer/ms/zx/rpn.zip (contains all versions on this thread)

I'd already written a screen-drawing routine for a "ZX81 Brain" version when I realised, it was a bit ambitious to make a calculator with all the scientific functions I could fit on it, until I'd tested the routines I'd need to set up on a simpler four-function version which I've called the "ZX80 Brain". (Such names were the bottom two skill levels of Starfire, the early, mostly BASIC-based release from Virgin Games that Codemasters would have called "Super Star Trek Simulator" - which is obvious when the game draws the ship's top and side views.) And I'm quite pleased that I've made some routines work in BASIC that I could never have come up with when I was a nipper:

- Loaded in the ZX80 character set (which I'd saved ages ago and I have a program to make defining character sets really easy).
- The number keys are all centralised into 2x2 squares by PRINTing them where I've put the stack with INK and PAPER the same, then reading the 6x7 areas with the POINT function and PLOTting them in the right place. If they'd only had to be centralised between two rows I could have used POKE 23606 to shift them vertically, but I needed to do it horizontally as well.
- Shown a "keypress on the screen" by temporarily turning on the BRIGHT channel for that 2x2 square and turning it off again when the process was done, with a POKE of the display file where the attributes are held. It may seem excessive to define an array - DIM z(90) - with 90 values, most of which are unused, but I'd read the keypress with LET i=CODE INKEY$, then z(i) would hold the address that needed to be POKEd (up or down by 64) for the top-left of the 2x2 square that I'd defined for that key on screen. It's four POKEs in total (value, +1, +32, +33).

I am not an advanced programmer by any means, I know next to nothing about machine code. But seeing as this is my level, shown here, imagine my delight when I managed to get those last two routines above to work without consulting anyone who would be able to do it in five seconds. That's the crucial point. (NOTE: the BRIGHT channel POKE is something I'd use a lot more regularly these days, now that I know how it's done.)

Other things I managed to check for, given that the number at the bottom of the stack has to be held in a string and that makes it harder, is:

- only keys shown on screen will actually do anything
- you're not trying to divide by zero
- the stack won't fill beyond 17 values or empty beyond a zero stored at the bottom
- the decimal point can't be entered twice
- there's no exponential key (in this version) but it checks to see if there is one anyway, for calculated values that are beyond 99,999,999
- leading zeroes aren't entered

It's slow, I know that - because I've written it in +3 BASIC which goes mad if I try to use redefined character sets on the BASIC editor, I've had to POKE 23607,249 every time I want to PRINT something on the stack, and POKE 23607,60 at the end of the subroutine every time. Hence I thought the "ZX80 Brain" was an appropriate name. For the "ZX81 Brain" version I could use the standard character set, but I thought I'd make it a bit like the early Sinclair RPN calculators and redefine 0-9, E and + to make it look like a seven-segment LED display in the stack, so I'll have to keep those POKEs in.

I know what you're all thinking: "...but the ZX80 couldn't handle decimals!" Well... like a "ZX80-and-a-half", if you like, it can handle decimals, but doesn't always get it right when checking that there is one. I've set two variables as flags - d and e, set to either 0 or 1. d=1 if there's a decimal point in the value at the bottom of the stack, e=1 if there's an E+ value in there; if one appears as the result of a calculation, d and e are both automatically set to 1. I've set d to 1 if the M key (for .) is pressed, and both d and e back to 0 once the ENTER key is pressed and that number is moved up the stack. I've used the variable o to hold the result of a calculation before the stack is moved, and I've checked:
IF o=INT o THEN LET d=0
IF o<>INT o THEN LET d=1 (both lines are in just to make sure)
IF o>=1e8 THEN LET d=1: LET e=1 (because such a number will be held in scientific notation, and even if it's one digit with no decimal point such as 1E+8, the decimal point key needs to be disabled anyway until this number is put into the stack).

Whatever I do, I find the decimal point flag gets stuck on and it beeps at me as if there's a decimal point there, even when there isn't. Sometimes it's because the display is holding a non-integer value but it can't display the decimal point because there are too many digits, other times it's a mystery.

And just to make it look like I'm doing a thorough job, the ZIP package contains the program in tape, +3 disc and microdrive formats, all with the LOAD command for the character set modified appropriately!

-------------------------------------------------------------------------
LATER IN MARCH 2017...

Hey! Great news! I've upgraded the "ZX80 Brain" calculator to the new "ZX81 Brain" version, complete with scientific functions - at least, as many as I could jam onto the screen and make work.

Image

Download link: http://www.rickdangerous.co.uk/hammer/ms/zx/rpn.zip (contains all versions on this thread)

Updated package includes:
- Tape (.TZX), microdrive (.MDR), +3 disc (.DSK) formats;
- Each of these contains the program, separate screenshot and redefined character set for the ZX80 Brain and ZX81 Brain versions of the calculator;
- ZX Printer listings for both the ZX80 Brain and ZX81 Brain calculators, taken from the tape format - in Spectrum graphics as a .PNG image and outputted to text as a .TXT file;
- Documentation, mostly adapted from the wordy waffle in these two posts.

The screen for the "ZX81 Brain" calculator was designed first, with 30 keys in a 6 × 5 array - the space for the top two rows in the "ZX80 Brain" version was instead filled with the ZX80 logo. I hadn't decided what extra scientific functions should be added on the top two rows when I switched to the "ZX80 Brain" version, so it gave me time to work out the best permutation of such functions.

For the "ZX81 Brain" version I could have used the standard character set, but I thought I'd make it a bit more like the early Sinclair calculators and redefine 0-9, E, + and - to make it look like a seven-segment LED display in the stack. This has meant I have had to keep all the constant swapping between the redefined character set (POKE 23607,249) and the standard character set (POKE 23607,60) to ensure the screen doesn't fill with junk in 128/+3 BASIC. (It's annoying, because I'd have liked to see the listing for the "ZX80 Brain" calculator in the authentic ZX80 font!)

The extra features the "ZX81 Brain" calculator adds over the "ZX80 Brain" are:

- a fifth "regular" function, the power key;
- the plus/minus key and the ABS function to convert any value to always positive (which was really a result of me having one key spare and not wanting to waste it...);
= a routine will disable trying to negate zero; ABS has no effect on zero
- trigonometric functions SIN, COS, TAN;
= the routine can check for values where TAN has an asymptote, but though it is correctly coded it won't always work (see "known problems" below)
- logarithmic functions, ln and log10;
= a routine disables taking logarithms of zero or negative numbers
- pi key
- reciprocal key;
= a routine will disable taking the reciprocal of zero
- square root key;
= a routine will disable square roots of negative numbers
= this is intended as a short cut, other roots are available by calculating powers of reciprocals e.g. cube root of x = x^(1/3)
- an exponential key allows values up to 10^38 to be entered (beyond which the program will stop with "6 Number too big" - see "known problems" below);
- an inverse function key, which inverts five functions and extends the exponent
= press it and the BRIGHT channel stays on until the next key press
= logarithm functions are inverted; ln becomes e^x, log10 becomes 10^x
= trigonometric functions are inverted; SIN, COS, TAN become ASN, ACS, ATN respectively
= a routine disables calculating ASN and ACS for values greater than +1 or less than -1
= using the INV key before the EXP key produces "E-" on the current entry instead of "E+" and allows entry of reciprocal scientific notation
= the key is always reset after the second key press; it will have no effect on any keys other than these six
- a redesigned screen to reflect the black, red and white of the ZX81;
- the aforementioned seven-segment character set, in bright red to look like glowing LEDs.

In a horrible twist of irony, the extra features added to the "ZX81 Brain" calculator - which mean many more key presses to check for in each program cycle - have slowed it down to the point where it really struggles with a full stack, particularly when executing a single-value function - there are more of these and five have inverses, which means there are a lot of lines of code to execute every time one is used! So the "ZX80 Brain" calculator is faster for the basics, the "ZX81 Brain" calculator can do more. (Of course, you could just use the Spectrum's functions in BASIC, I've just made them look flash with all my screen POKEs!)

Features I haven't managed to get on this calculator (and would never have been likely to anyway) are:
- non-decimal number bases (binary and hexadecimal at least) and the ability to convert between them;
- complex numbers;
- logical operators NOT, AND, OR and XOR;
- angle measurements other than radians (degrees, mils, grads... whatever they are!);
- degree-minute-second notation;
- fractions;
- hyperbolic functions (though these can be calculated with exponential identities);
- derived trigonometric functions (SEC, CSC, COT - though these can also be calculated with reciprocals of COS, SIN and TAN respectively, and has anyone ever seen these on a scientific calculator, let alone an 8-bit micro?)
- average and standard deviation calculated from all the values entered into the stack.

Known problems:
- doesn't always recognise when a number no longer has a decimal point, usually because there is a very small decimal in the string that the number display can't handle when it tries to print VAL of the string.
- no exponent key, but the calculator can handle numbers from 10^8 to (somewhere between 10^38 and 10^39) as the result of a calculation. Any calculation that exceeds 10^38, or an attempt to press number keys that take the exponent above 10^38, will crash the program with "6 Number too big". (This also happens with exponents below -38.)
- exponent key added; so far there appears to be no easy way to prevent the exponent from exceeding 10^38 accidentally, or as the result of a calculation. (Believe me, I tried, and setting the correct flags, trying to read the exponent as a separate part of a string called f$ and a numerical value f (=VAL f$) at the same time without one or the other getting out of hand was huge, convoluted, slowed the program down even further, and never worked properly. Just be careful around large numbers, right?)
- PI is stored to 7 decimal places. Trig functions work OK except in certain cases where the value of the trig function should be 0 but the accuracy of the stored value of PI is not enough and the function returns the value 7.3145904E-10.
= e.g.: if X = PI*0.5, COS X should be 0 but returns 7.3145904E-10; the same result occurs with COS of-PI*0.5. Strangely, using PI/2 returns the correct value 0. Higher values of X where COS X should equal 0 - i.e. PI*1.5, PI*2.5, etc - are fine whether using PI*1.5 or 3*PI/2. TAN of -PI does the same and TAN of multiples of -PI returns the same multiple of the inaccurate value - i.e. X = 2*PI, TAN X = 2*(7.1345904E-10).
= annoyingly, this means the attempt to check for asymptotes in the TAN function fails for any value of X for which this program will return COS X = 7.1345904E-10; this is because it does not recognise the variable OT = ((s(1)+(PI/2))/PI as being an integer (because it's very slightly off, not even enough for the display to handle) and an attempt to evaluate TAN X returns a very large value that crashes the program with "6 Number too big". The routine does at least work in theory - divide PI by 2 (don't multiply by 0.5!), COS returns 0, TAN will beep for an error.

-------------------------------------------------------------------------

As I've been asked to do, when I'm done with these weekly dumps (and there might only be one more unless I get digging) I'll allow them for submission to ZXDB. Anyway, have fun with this little lot, if you weren't too traumatised by maths lessons at school all those years ago.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

Dump Mark Two didn't get a hint of interest in two weeks and that makes me a saaaaaaaaaaad panda. So, I expect little more success with Dump Mark Three as it's more maths-related programming, though at least this is more up to date. T'other forum had gone walkabout last weekend, and I needed it to return to recover the post, which is here now for your confusion and dismay.

-------------------------------------------------------------------------------------------------
FROM 29 MARCH 2020:

In a break from typing in listings from 37-year-old magazines, I had a sudden urge to write a maths-related program, as I do, occasionally. Some, such as a cubic equation solver, remain unfinished as I still don't quite understand the methods behind it (but I'll probably have another go at some stage). And others, such as the RPN Calculators I made three years ago (SEE ABOVE), I've made public because I thought they were good enough to show off and the listing would probably have been snapped up by Sinclair Programs, had I been in my 30s or 40s in 1983 (I wasn't... I was a tenth of that) and had a huge stack of tapes, and a printer, and an enormous amount of that shiny paper to print out the listing until I could work out how and why it was going wrong, when at least these days I have an emulator with savestates to make the programming process a whole lot easier.

So this is what I did.

Image

Download the package here: http://www.rickdangerous.co.uk/hammer/ms/zx/hexfrac.zip
(and see also below...)

In short, I thought it was possible to make a program to convert fractional decimals into their hex equivalents - and include some test examples - pi, e, and the usual suspects. After one very false start after which I almost abandoned the whole idea, I went through with the process of "multiply by 16, take the value before the point as the next hex bit, replace that with a zero and continue". For the most part it works, and the input will take a string of 30 digits after the decimal point. Decimal expressions that terminate within those 30 digits will come out exact; irrational numbers and recurring decimals, because they are 30-digit approximations of the actual value, will not be so accurate. I found pi would calculate to 13 hex digits after the point; e, the golden ratio and the square root of 2 were all accurate to 24 digits. The final result will be printed in just under four minutes, so even on real hardware you can give your input, start the process, make a mug of tea and come back to find it's nearly done.

Not bad for a day's programming, that - and I now further wonder if it could be down-converted for a ZX81. Even once the colour information and the UDGs are removed (which requires the maximum number of digits to be cut to 29 at most), would 16K be enough memory to handle the same process? I suppose there's only one way to find out...

-------------------------------------------------------------------------------------------------
LATER, THAT SAME DAY: (I think I must have posted the Spectrum version just after midnight...)

It is doable, and I've done it, in the space of a morning:

Image

The graphical compromise that was the loss of colour has been compensated for by (a) using the ZX81's "shades of grey" graphics around the input and output values, and using inverse video to show the build-up of the hex bits instead of BRIGHT. The number of accessible digits after the decimal point is reduced to 29, and you'll know if your input is too long as the "L" cursor, with quotes intact, will spill onto a second line (and the BEEP-less error routine compensates for this). This is so that there's two character spaces for input integers from 10 to 15.

Otherwise, the program works as I'd expect, and the accuracy hasn't been reduced by much for the loss of that one decimal place - the golden ratio loses two digits of accuracy but pi, e and root 2 are unaffected (although the digits after this point are different).

The major difference is in the speed the program works. I've just tested the Spectrum version on a real +2B, and it reaches a result for a 30-digit input in three and a half minutes. The ZX81, handling 29 digits, will get there... in 17 minutes, at least on the EightyOne emulator running at normal speed. I don't have a real ZX81 to test it with, but if anyone does, feel free to convert the .P to .WAV and give it a shot.

It's lunchtime, so I've earned myself a corned beef sandwich - at least I would have if all my tins of corned beef weren't stashed away in a Corona-chan Doomsday Box, which I refuse to open unless absolutely necessary. So yesterday's freshly-baked bread - yes, I've been trying that myself - will have to be filled with something else. But I'll find something, that's for sure.

Also, anyone who wants to translate these two programs into machine code to see how they run that way, fire away. I'd be expecting the Spectrum to zip through the routine in no time at all.

I further wonder now, if it's possible to do anything similar on a (16K and probably emulated) ZX80 - losing the PRINT AT commands will be tough, losing floating-point arithmetic will be even worse, and the long multiplication routine as I've written it needs that facility.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

I am rather less of a saaaaaaaaaaaaaad panda this time because I didn't have anything more to add to this thread after last time (that I thought worth it, anyway). And to break the silence, here's something I made... this evening. Well... here's something I modified this evening, at least, and that's why it didn't take long.

I've taken the hexadecimal fraction converter from the post above and adapted it for dozenal, to satisfy all those who demand that we should have evolved to have six fingers on each hand and thus count in base 12, or who want to go back to the good old days of pounds, shillings and pence.

Both the Spectrum and ZX81 versions of the hex fraction converter program have been adapted.

Spectrum version:
Image

ZX81 version:
Image

There are many representations for the extra digits ("dek" and "el") required for the values of 10 and 11 - A and B, X and E, T and E, chi and epsilon, or the upside-down 2 and 3 that look like a very mangled T and curly E (or epsilon). On the ZX81 it was far easier to keep them as A and B rather than try to fanny about with X and E(which was the original plan), seeing as A and B follow on directly from 9 in the ZX81 character set. As they don't on the Spectrum there had to be separate lines to represent any digits beyond 9 (which was also the case in the hex program), so I defined upside-down 2 and 3 UDGs to make them look like the Dozenal Society of Great Britain would want them to.

Also, the semicolon isn't a mistake, it's how the radix point is denoted in dozenal.

Download the package here: http://www.rickdangerous.co.uk/public_html/hammer/ms/zx/dozfrac.zip
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

Who's been a brainlet? Hands up here.

The link should be: http://www.rickdangerous.co.uk/hammer/ms/zx/dozfrac.zip

But you all worked that out already, right?

If these Hex/Doz fraction converters are worth including on ZXDB I'll probably combine them into one package (i.e. both programs on one tape, disc or microdrive) for the Spectrum version at least.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

Image

This is a program I've had kicking around since at least 2002, and I've occasionally added to it since then (though not since 2006). It generates UK number plates, in white and yellow.

So I picked it up again (after watching a lot of HubNut videos, if you must know), and over the last couple of days I streamlined the BASIC - cleaning up variables, subroutines and the like that were a bit of a mess - and got that working with very few visual changes to what it was 14 years ago. Here's what it generates:
- 2001-present style plates up to the "20" series (i.e. AB20CDE)
- 1963-1983 suffix plates (i.e. ABC123A) and 1983-2001 prefix plates (i.e. A123ABC), including Q prefixes for kit cars
- Basic Northern Ireland plates with the most recent three letters, four numbers combination (e.g. ABZ1234, AIB1234)

The screenshot above is what I did today, making as good an approximation as I can get of the Charles Wright Narrow font that fits into two character squares. Letters are defined using capitals for the top half and lower case for the bottom half, numbers use their standard character for the top half and "CODE minus 176" (space to closed bracket) for the bottom half, most of which correspond to SYMBOL SHIFT plus the number.

There are a few "quirks and features", as Doug DeMuro would say, where I've done as much as I think I can to make the plates realistic:
- Plates up to a J suffix (31 July 1971) always appear as white on black.
- The Doovla specifies "undesirable" three-letter combinations that it will never issue (e.g. SEX, GOD, JEW and some odd ones like ABF) that I've held in a DATA statement - these are excluded, and so are the Manx three-letter combinations MAN and *MN.
- Likewise, "undesirable" two-letter combinations in 2001 plates (e.g. FU, NF) or others set aside for special use (e.g. GO, DR) as well as the J*, T*, U* and XG-XY combinations that were not assigned to regions have been excluded.
- Also excluded were the number combinations from prefix plates that were set aside for special use (i.e. 1-20, and all multiples of 10, 11, 100 and 111). Such numbers on suffix plates are fine, as the Doovla hadn't yet worked out there was money to be made that way.
- There are other oddities such as the abolition of X* as regional identifiers in the 1963-2001 plates after 1974 (and some had already been scrapped in 1964). I've taken this into account in a compromised way, in that *X* combinations can only occur on a black plate. Hence, you'll never see Richard's Rover SD3 from early episodes of Keeping Up Appearances (D541EXL, which is invalid), but you might see its replacement when the BBC realised their mistake (D541EFL) or the 1966 reverse version (EXL541D, which is valid and would appear white on black).
- Some regional identifiers were scrapped (e.g. *SY) or never used, but even though a table of these is available it's far too much hassle to implement it correctly so I haven't bothered. Plus it would slow down the program far too much more than it already is.
- Northern Ireland plates only show regional identifiers that have been used in Northern Ireland with the current system (three letters, four numbers) - so it's not just a random I or Z thrown into the second or third letter. For example: Belfast uses or has used *OI, *XI, *AZ, *CZ, *EZ, *FZ and *GZ as the second and third of the three letters; reverse combinations with a Z in the middle, for instance, were all used in the Republic of Ireland before the 1987 reform and are not included here. There's no way of knowing how far the current registrations have progressed, so I've allowed any combination from the current series (i.e. anything from AGZ1001, which is almost certain to have been issued, through to YGZ9998, which has not). The only recent combination I missed out was *YZ, used in County Londonderry (careful now) since January 2020, so there are barely any of them out there.

It's unlikely anyone will want to see this program in action, and besides I've got a bigger plan for it, so I'm not putting it on general release just yet, unless anyone wants to ask for a copy.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

(Potentially) useful utility time!

This is a short(ish) program that I found I needed when trying to grab data from the display file and dump it elsewhere. For instance, for any given PRINT AT position, what are the eight addresses for the eight rows in the display file, and what address are the attributes held at?

I didn't have such a program, so I wrote it, with a lot of fiddling around with a spreadsheet. It also has PLOT positions thrown in for good measure.

Input PRINT AT coordinates (including the use of rows 22 and 23, i.e. the INPUT area) and the program returns the range of PLOT values in that square, the eight addresses for the display file, and the attribute address. PLOT coordinates will not be given for the INPUT area.

Input PLOT coordinates and the program returns the PRINT AT square the pixel is located in, the eight addresses for the display file, the attribute address, and a POKE for the display file that will insert a pixel at that position. Note that multiple pixels on the same row will require the values for the POKE to be added together - but you all know how the display file works, don't you?

Input a display file address and the program will first check to see if it is where pixels or attributes are stored. The program returns the PRINT AT coordinates, the PLOT range for that square, all eight display file addresses for that square, and - if the input is in the pixel range - the attribute address.

Image Image

Image Image

GET IT HERE, said Blackadder one day in a fit of desperation...
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
PeterJ
Site Admin
Posts: 6855
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: Dr. Jim's BASIC dumping ground

Post by PeterJ »

This looks excellent [mention]TMD2003[/mention]. Thank you for sharing.
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

See this thread for more details...

Here's the original C64/PET program - "Computer Haiku" by Commodore Educational Software, 1983

Once I'd discovered the original program was written in BASIC I thought I'd examine the listing and convert it for the Spectrum. Obviously, all the colours were going to be different and the layout was probably going to be different seeing as the Commie can handle 40 columns at a time.

Most of the original code was discarded as the Bread Bin has no PRINT AT or colour commands, and uses massive strings of system variables, POKEs and control characters instead - so the title screen, menu and instructions sections were all rewritten to make them look like the original, just in different colours. More system variables and control characters had to be worked round from line 1000 in the original (660 in this version), to make the haiku appear as it should. Generating it in the first place was more complicated on the Commie as - for reasons only known to the original programmer - the random number generator was set by the system timer. I thought it unnecessary to PEEK 23672 (the Spectrum's equivalent) and translate that - it's just using RANDOMIZE at the start of the program and then taking whatever comes from then onwards. The second line had to be generated first, so that the length of the line could be checked and junked if it was over 32 characters - one place the Commie had an advantage. I think my introduction and exit screens are far better than the original, though.

The original was full of error-checking routines which were unnecessary on the C64 but which would stop the program in its tracks if it was run on a PET that couldn't handle it. (There was probably a VIC-20 version as well, but with its horrifically limited text screen, everything would spill over onto two lines.) None of these were needed - all I had to do was condense the program after I found out it couldn't be loaded on a 16K Spectrum (see that as the equivalent of a PET in this case). This involved removing all the REM statements - which I've shown below just in case anyone wants to examine the structure of the program and make it easier - but it also meant wheeling out the old 1K ZX81 trick of using NOT PI, SGN PI, INT PI and a ton of VALs every time a numerical value appeared... and there were a lot of them. Still, that meant plenty of bytes were saved, and the program would run on the smallest Spectrum with ease. It now looks like a complete mess, but at least on a Spectrum the memory-saving tricks don't slow the process down anywhere near as noticeably as they did on a ZX81.

Image Image

Download the program
Write computing-based haiku
You have much honour.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

In the beginning (28th March 2020), there was the Spectrum Hexadecimal Fraction Converter. A day later (and definitely not a dollar shorter), it spawned a slightly cut-down (and a lot slower) ZX81 version.

Later, in August 2020, a Dozenal Fraction Converter for both machines joined the Hexadecimal counterparts.

And now... it's time to unleash the awesome thromping power of... THE QUANTUM LEAP.

Image Image

Image

Image Image

Image

I've combined both programs, and converted them for the QL. Look at the result, there, in all its majesty.

The reasons are obvious: the Spectrum's accuracy for conversion was limited by the number of digits after the radix point that could be kept on screen at any one time, if we want to see the computer show its working. The Spectrum could handle 30 digits, by cunning use of user-defined graphics for the numbers 10 to 15 (as well as those for "dek" and "el" in the dozenal system). The ZX81 had no such facility, so had to sacrifice one of those digits. The QL, in Mode 4, can display 85 digits across its screen. So there's only four colours available - but colour isn't important, this is all about accuracy. Knowing that there would need to be space for two digits in front of the radix point, this meant that it could accommodate 82 digits after the radix point - giving us a level of accuracy that still won't trouble WolframAlpha (where do you think I found all the values of the constants in two non-decimal number bases?) but will blow the Spectrum into the weeds.

The principle is exactly the same as before - take the string of numbers after the radix point, multiply the block by 16 or 12, the digit that appears before the radix point becomes the next digit in the final sequence, then this is subtracted to leave only the digits after the radix point, and the process repeats. As with the Spectrum and ZX81 versions, it's all shown on screen.

The other reason for converting this program to the QL was to get to grips with its far more convoluted user-defined graphics. The QL's character set has a whole load of foreign characters and symbols between CHR$ 128 and 190, all of which can be redefined if you know what you're doing, though the process is more similar to redefining an entire character set on the Spectrum, in that if one character is redefined, the rest disappear into oblivion. So even though I only needed two characters - for the dozenal "dek" and "el", I had to redefine the down-arrow, pi and phi symbols, and threw in an empty box for good measure. It look a long, hard, frustrating amount of battling with POKEs and PEEKs and channel pointers to understand it, and members of the QL Forum are trying to tell me I'm doing it the hard way, and these days with QL Toolkit II there's a CHAR_USE command which allows easy access to custom characters on multiple channels. Well, in the words of Frank Sinatra, I did it my way.

Or, rather, I did it David Nowotnik's way, because the routine I used is based heavily on the "Lunar Lander" program from his "QL Characteristics" article in the October/November 1985 issue of ZX Computing. By starting out with a routine that would print his UDGs in window #3, I eventually managed to get them to be defined to any channel from 0 to 8, and then start defining the block from a character other than CHR$ 128 (161 is an ideal start point, so that the characters are produced by CTRL+SHIFT+A, CTRL+SHIFT+B, and so on).

The QL is a faster computer than the Spectrum, but it has 82 digits to contend with rather than 30, so it isn't too surprising that it takes a chunky 13 minutes, 24 seconds to produce a full answer. Here's the comparison below with the real values, as well as how the QL measures up against its older Z80-based siblings.

And a bonus point - this program also showed me I had made a mistake in the value of pi in the Spectrum and ZX81 programs, so these have all been updated to version 1.1 and the accuracy of their calculations has been corrected accordingly! And, strangest of all - the ZX81 was MORE accurate than the Spectrum for both hexadecimal and dozenal calculations of pi!)

Download the NEW version 1.1 of the Hexadecimal Fraction Converters for the Spectrum & ZX81

Download the NEW version 1.1 of the Dozenal Fraction Converters for the Spectrum & ZX81

Download the all-singing*, all-dancing Hexadecimal & Dozenal Fraction Converter for the QL


* NOTE: may not be "all-singing", or if it is, it'll all be off-key due to the QL's horrific implementation of sound in SuperBASIC. Think of Edith in 'Allo! 'Allo! and you'll get the idea. But despite its sonic shortcomings, this package does come with information about QL emulators and loading instructions for the raw beginner, which I was until April this year.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

There's an F.A. Cup simulation from ZX Computing in 1983, which I typed in back in the day. This is its original version, though I've spotted a bug in the listing, and whoever typed it in thought "aha, I've fixed a bug!" but actually introduced one instead. I'll get that corrected soon enough. I've also modified it quite heavily, improved the sounds, tidied up the colours, and added a 42-character print routine (the one I was trying to find the origin of the other day) so that the teams could have 18 characters in their name.

However, for this season, Hampton & Richmond Borough have come all the way through the qualifying rounds to reach the First Round proper. And with 26 characters in their name, they're going to need a bigger boat... I mean, screen.

lrun mdv1_dr_jim_writes_for_the_ql_again_bas

Image Image

Of course, the QL comes to the rescue. There were a few slightly annoying roadblocks in converting this program to QL SuperBASIC, but I reckon it's all there. The QL isn't known for its colours in Mode 4 but I thought green for one season and red for the other would suffice - and I've included the teams from the 1982-83 season, i.e. when this program was first written, and 2020-21, where we are now. The fortunes of some of the teams have changed - not least Notts County, who were in the old Division One for the 1982-83 season, but aren't even involved in the 2020-21 First Round as some of their players tested positive for the Chinese-Bubonic-Plague-meets-Ebola-meets-Leprosy and they had to withdraw - but given that they should never have found themselves in the position they are now, in the National League, they really only have themselves (and their catastrophic mismanagement) to blame. (King's Lynn Town are in their place, which should make Martin Brundle and George Russell happy, at least.)

The same restriction applies to this QL version as in the original - that multiple replays always result in the teams being reversed from the original replay, i.e the home team in the original draw will always be the away team in all the replays. Then again, this was a type-in, not a commercial release. Other than that, I wonder if the QL has a different way of generating random numbers; even accounting for the built-in (and intended) bias towards home teams and the difference between the divisions, the first time I ran this simulation with the 2020-21 teams, Harrogate Town - newly-promoted into the Football League this season - beat Blackburn Rovers in the final. (The second run saw Chelsea win, which is more realistic, but still, anything's possible here).

And despite the QL's horrifically wobbly sound capability (in SuperBASIC at least - machine code may be able to do a lot better), I've made it beep out an off-key version of Back Home, which was resurrected int he mid-1990s as the theme tune from Frank Skinner & David Baddiel's Fantasy Football League. This is a Fantasy Football Cup, but let's not argue over small differences. All together now: "Saint aaaaaaaand Greavsie talk about the Endsleigh League, as if it's iiiiiiiiimportaaaaaant..."

Download the QL F.A. Cup - includes detailed loading instructions for QL noobs.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

The BASIC Dumping Ground has been rather quiet recently, mainly because I've been experimenting with machine code... and two-timing the Spectrum with other machines. Actually, it's more like four-timing, or if you count everything I had to load up for a few rounds of multi-platform Ghostbusters recently, it was (I think) nine-timing. Anyway, enough of my electronic harem, let's make some noise...

Image

MACHINE CODE BEEP SEQUENCER

This is a program I wrote in a few hours when [mention]R-Tape[/mention] started asking me for more BEEP sequenced programs than what I'd already done. I'd only sent the bassline for Deee-Lite's "Groove Is In The Heart" in a series of BASIC BEEP statements, to make it absolutely unambiguous what the pitch was to be and how long each note was to go on for (as well as putting a few PAUSE statements in there as well). Dave then sent me the assembler, so I could load it in Spin and check that the lengths and pitches were correct. This was, indirectly, how I found out about machine code BEEPing - plus I'd seen a routine somewhere that used CALL 949, so I thought... this must be how it's done. Load HL with the pitch, load DE with the duration, CALL 949... except, it's not that simple because DE is the number of cycles to be BEEPed, rather than a specific amount of time - write BEEP x,y in BASIC and the ROM routine to handle BEEP translates x and y into HL and DE values for each note.

So if I was going to make my own rudimentary machine code tunes, I'd need to write a program to work out all the HL and DE values I'd ever need. After analysing as many different HL values as I could by piping them into Audacity and measuring the length of the cycle, eventually I gave up trying to work out the exact frequency that a given HL value outputs, and opted for Jonathan Cauldwell's method in his "How to write Spectrum games" guide. Start with a pitch, work out HL from that, and then work out DE from the duration, and HL, and a duration-multiplier that acts as an effective control of tempo.

That's what this program does. It accepts an input of any note from A0 to C8 - the span of a full-size piano keyboard. It will show the note given, the BEEP pitch for BASIC, and the HL value that corresponds to that pitch, loaded from a Number Array: block. The rest of that Number Array: contains the values of DE for exactly one second, which correspond to the frequency of that note in Hz.

Input the note first - A to G, upper or lower case, with "#" or "b" for a sharp or flat. Input "O" to change the octave at this point instead of a note. Then input the duration in beats - the time in seconds will be shown on screen, but the number of beats will be stored in the array that holds the whole tune. The HL and DE values will appear on screen. Input "P" to play the sequence, then you can adjust the tempo, print the entire sequence, add some notes, or edit the sequence from a particular point.

I have probably made this program sound more complicated than it is - really, it's a very crude routine that could serve as some kind of introduction to machine code BEEP sequences for those who have never tried it before. It can't handle pauses so your input will have to be a constant stream of sound. So it's a very, very long way from BEEPola - but it might still be useful to someone, somewhere, at some stage.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
zup
Manic Miner
Posts: 208
Joined: Wed Jul 08, 2020 8:42 am

Re: Dr. Jim's BASIC dumping ground

Post by zup »

I've tried to download your games, but most enhanced type-in files can not be downloaded. The links point to .../zx/(program).zip when the actual files are placed on .../zx/files/(program).zip.

Thanks.
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

zup wrote: Wed Dec 23, 2020 6:44 am I've tried to download your games, but most enhanced type-in files can not be downloaded. The links point to .../zx/(program).zip when the actual files are placed on .../zx/files/(program).zip
Well spotted. As I don't have to download my own files, I'd probably never have noticed. Every link except Apple Thief was broken, and I also found a row of ****************** in the links for Hex Bin Converter, Pencil and Stunt Rider that needed filling in - they're not listed on ZXDB and I'd probably meant to put something like a link to the listing in.

The links are now all fixed. I'm going to have to test the whole site now to see if anything else has escaped my attention!
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

Time to wake up this thread! Seeing as I'm running an entirely different programming competition that I can't contribute to, I've been rather quiet on the programming front. I've got a few ideas in development, but this is the only one so far this year... and it was written in one evening. In short, I'd always wondered if I could translate Stephen Keevil's Lissajous Figures, from the July 1983 issue of Sinclair Programs, for the QL, using its more powerful graphics. So I did... well, sort of. In effect, after I'd defined custom windows, all the input and error-checking procedures, and adapting the one line that actually calculates the points that form the figures, there was just about nothing left of the original...

But anyway, here it is. Take the Spectribution page or the direct download, either will do. It'll run on an unregistered version of QemuLator at regular speed, though if I can ever adapt this to make it into an animated version with constantly changing phase angle, it'll probably need a 640K+ QL and probably a Gold Card as well.

Image
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

I must wake the BASIC Dumping Ground once more to offer something that might, possibly, be of help to those who haven't yet worked out machine code. There were a few who were giving it a shot, such as [mention]Ingerson[/mention] who's new here and made a thread about it, and I've found another one from [mention]Freespirit[/mention] further down the Programming forum.

Presenting the generically-titled Text & Screen Tools:

Image

This is what you can do with it - the demonstration program that comes with the machine code (all 178 bytes of it!) tries to explain it all briefly, but I can do a bit better when I have some text space to spare.

First, prime the machine code with the PRINT AT position of what you want to affect. POKE 60000,(row) and POKE 60001,(column) - a subroutine within the machine code will be CALLed to translate these two one-byte values into a two-byte value that is the first row of pixels for that position in the display file. It can be done in one line of BASIC (thanks to Dilwyn Jones, incidentally, in the days before he became "Mr QL"), but even though the machine code looks complicated (and contains a multiplication routine from "40 Best Machine Code Routines" by Hewson Consultants) it can be worked through and achieves the same result, only a lot faster.

Now, RANDOMIZE USR 60056 and that character square will be turned into bold text. What it does is it takes each row of pixels, shifts them one place to the right and ORs them with a copy of the original. Do this twice on the same square and you'll have an ultra-bold version that Ste L. Cork was very fond of using on his games (e.g. Sector-90, Colony, Wibstars).

Or, you could RANDOMIZE USR 60071 on the square instead, and the bottom four rows of pixels will be shifted left by one place, producing an italic text effect as used by BASin (at least, BASin For Beginners, which I still use because it does what I need it to do, even though I'm a long way from being a beginner in BASIC).

What I find useful when making screens for my Crap Games - and this is why I've done it now, because I'm preparing my assault on the 2022 CSSCGC already - is that BMP2SCR's algorithm outputs character squares that I find are the wrong way round when I try to edit the screens in ZX-Paintbrush. Each time I'll be drawing away with a dark ink colour on a light paper, and then suddenly a square will invert, and I have to manually swap the paper and ink to continue editing. So I'll use this program to hard-invert the offending squares before editing them. It can do the following, again after 60000 and 60001 have been POKEd with the desired PRINT AT position:
- Hard-invert the square - i.e. all eight rows of pixels will be CPLed to their inverse, and the INK and PAPER colour will be swapped in the attributes. RANDOMIZE USR 60002 to make this happen.
- You will also need to check that the inversion has happened by examining the screen with attributes turned off (i.e. completely turned to 56 which is black on white). RANDOMIZE USR 60140 to store the attributes at 62528 (i.e. 40000 above where they usually are), RANDOMIZE USR 60152 to turn the screen to black on white, and RANDOMIZE USR 60166 to get the attributes back again. All three are simple LDIR routines.

So if you're struggling with machine code, take a look at this. I've provided a fully-annotated .ASM file in the package, so that I can still understand how it works after several months away, and by changing the ORG value it can be reassembled to a different address - just remember to note where all the routines start.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

Following on from the Lissajous Figures conversion on the previous page, here's something I promised to the QL forum: Spirograph.

Image

There are two screenshots here forced into the black-box-QL aspect ratio.

It's another conversion from a Spectrum original - here's the original listing - it's short but managed to pack in a (rather messy) intro screen as well as its ability to draw the familiar Spirograph patterns. I've retained everything the original had, including the facility to overprint one pattern onto another (and I don't think I needed to set OVER 1 to do that, although I did), and load and save screens from/to microdrive. (SBYTES mdv1_filename_bin,131072,32768 is the equivalent of SAVE "filename" CODE 16384,6912 a.k.a. SAVE "filename" SCREEN$ for those who were curious.) What I've added to this version is the layout - a square main window #1, around which I'd fit everything else - so window #2 is the status display on the right (that's still a usable 27 characters across) and window #0 has been crammed into the bottom right - that's just the input area, as you'd expect.

I wonder whether the formula used to draw the patterns is correct - I've transferred it directly from the Spectrum original and can confirm that the same input of the three radii required will produce the same pattern on both Spectrum and QL. I remember, though, when I had a real Spirograph when I was a nipper, there was some combination of gearwheels with the pen right at the edge of the inner gear that would make narrow loops right the way across the drawing area. I haven't been able to replicate that with any combination of radii that I've tried, and I don't have a real Spirograph to test it with now (and, realistically, why would I?) And I was quite rubbish with Spirograph, really - I never had the coordination to keep the pen in place while keeping the inner gear meshed with the outer gear, so everything I tried to draw looked like the mess that it was always going to be.

Who here has kids in single figures? Show them this. They might even want a real Spirograph for about five minutes.
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
TMD2003
Rick Dangerous
Posts: 2032
Joined: Fri Apr 10, 2020 9:23 am
Location: Airstrip One
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by TMD2003 »

"Dr. Jim's BASIC dumping ground" is increasingly as badly-named as "The Hitchhiker's Guide To The Galaxy Trilogy", as I present yet another foray into machine code, but this time, it's a big one. Relatively speaking.

Hex Bin Converter is a listing from the March/April issue of Sinclair Programs that I've found very useful, enough to convert it for the Spectrum for ease of use, rather than keep whipping out EightyOne to load it. It uses string arrays and manipulation to forcibly convert any two-byte input in decimal, hex or binary to the other two. Most of what I'd need, though, is the conversion of decimal into hex or binary (the latter being the reverse of the Spectrum's BIN function), and I thought I'd tackle this with machine code.

So I wrote a simpler routine that takes a one-byte input, POKEs it into a single address (which is obviously held in binary), and then uses the BIT instructions to analyse the value bit by bit, and LD either a 0 or a 1 into eight further addresses, thus producing a binary equivalent of the decimal input that's easily readable from BASIC using PEEK. The decimal value is then further analysed, blanking half of it off with AND 240 (followed by four RRCAs) or AND 15, to split it into two values from 0-15, which are then converted to the character codes of 0-9 or A-F.

This took 114 bytes, which was long because all those BIT instructions are two bytes each, all needing that CB "shift", and they can't be looped.

So I made a "Mark II" version, where the BITs were replaced by a couple of nested loops in which the bit analysis is done with AND 128, AND 64, AND 32 etc. - and that can be looped, because the ever-halving value can be held in a register and RRed. This cut the routine down to 69 bytes.

The next step was to transfer the "Mark II" routine to the ZX81, which resulted in a further reduction to 57 bytes as there was no longer any need for a subroutine that checks whether the values in the hex conversion are 0-9 or A-F. Whatever the value, add 28 to it and that's the hex digit equivalent of 0-15, as the letters - capitals only on a ZX81! - follow immediately after the numbers. Weren't the ROM programmers thoughtful, not using ASCII?

And then came the big challenge. With a bit of assistance from [mention]1024MAK[/mention] and other users of Sinclair ZX World (where most of you aren't looking), I've managed to bash the ZX80 into some sort of suitability for machine code. For those of you who the old yoghurt pot completely passed by, it's not usually possible to hold machine code in a REM statement on the ZX80 as any character code from 64 to 127 is unprintable and will either corrupt the display or crash the computer - and that's where most of the useful LD instructions are. Toni Baker's method of using the ZX80's variables area to store machine code is, by the looks of things, the best way: for a program of length X bytes, put DIM Q(X/2) as your opening line to make sure this is the first variable in the area. Then, you have to run the machine code starting at "two more than VARS" - which will change according to the length of the program.

Mark's example of how it's done on SZXW has twice the number of BASIC lines that it needs. Rather than a series of POKEs, I installed the machine code with LETs, having first worked out what the combination of two consecutive bytes U and V would be. (In this program, U = 30 and V = 255 for LD E,255; U+256*V = 65310, and as this is greater than 32767 we require a negative number, in this case 65310-65536 = -226.)

With the code installed, the entire program was deleted, except for the initial REM statement, which holds the hex and binary output from the routine. And that's fine, because all that's ever going to be contained in it are the characters 0-9, A-F, CHR$ 0 (space) or CHR$ 1 (quotation mark).

Then the demonstration program was entered, and the result was a little over 400 bytes, including the machine code stored in the invisible array, for a program that's (sort of) user friendly. I could probably expand it to a two-byte version, but seeing as that involves calculating the low and high byte values in BASIC first so that they can be POKEd (in the absence of the QL's two-byte POKE_W), you may as well just work out the low and high bytes, and run the machine code twice with each byte.

Looking at the ZX81 listing and the way it uses string slicing to achieve its goals, it looks like it would be extremely difficult - maybe impossible - to make a decimal to hex and binary converter in ZX80 BASIC. It would certainly need a serious memory expansion But, as you can see here, it is possible (a) to do so in machine code, (b) to do so on an unexpanded 1K model, and (c) to actually get any machine code to work on the ZX80 in the first place without being a Level 60 Mage like Paul Farrow.

And for anyone who wants to know how it was done (fellow machine code noobs, watch and learn), I've put a fully annotated listing in the ZIP package, along with a spreadsheet that worked out all the values I had to put into the array Q.

Image

Image Image

Hex Bin Converter for ZX80 - grab it here!
Spectribution: Dr. Jim's Sinclair computing pages.
Features my own programs, modified type-ins, RZXs, character sets & UDGs, and QL type-ins... so far!
User avatar
1024MAK
Bugaboo
Posts: 3104
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Dr. Jim's BASIC dumping ground

Post by 1024MAK »

TMD2003 wrote: Tue Aug 17, 2021 9:31 pm Mark's example of how it's done on SZXW has twice the number of BASIC lines that it needs.
The program linked to was for demonstration purposes only. ⚠️ WARNING⚠️ This program has Commodore 64 influence. This program is not to be used for life support, in any part of any critical system, in any part of any nuclear reactor or power station control system, or for any commercial purposes. This program may fail to entertain if used in an entertainment application. No income tax, no VAT. No money back, no guarantee… You are strongly recommended to be sitting on your towel just in case of any problems :mrgreen:

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
andydansby
Microbot
Posts: 147
Joined: Fri Nov 24, 2017 5:09 pm
Location: Syracuse, NY, USA
Contact:

Re: Dr. Jim's BASIC dumping ground

Post by andydansby »

Nice Lissajous curves. I have a bit of an interest in them. Did my own project in Z88dk. https://github.com/andydansby/Lissajou ... ose-Curves.

I use a sine estimation to speed mine up as well as compiling the code.

Andy Dansby
Post Reply