Cool: [Archive.is/WayBack] em-dosbox – Windows 3.11 on the Web.
Via [WayBack] JRWR – Forrest F. on Twitter: “I love this thing, http://vrcade.io/win311 Boots into Windows 3.11 with a internet connection (over a fake modem!)”
–jeroen
Posted by jpluimers on 2021/03/22
Cool: [Archive.is/WayBack] em-dosbox – Windows 3.11 on the Web.
Via [WayBack] JRWR – Forrest F. on Twitter: “I love this thing, http://vrcade.io/win311 Boots into Windows 3.11 with a internet connection (over a fake modem!)”
–jeroen
Posted in History, Windows, Windows 3.11 | 2 Comments »
Posted by jpluimers on 2021/03/08
This is so cool: [WayBack] Glenda 🐰 on Twitter: “You are likely to be eaten by a grue! Just finished a new #NerdStitch cross stitch project- Zork 1 (Apple II version). The second adventure game I ever played. #zork #EatenByAGrue #apple2 #Infocom” .
That cursor!
Posted in Fun, History | Leave a Comment »
Posted by jpluimers on 2021/03/02
A few things to learn from [WayBack] delphi – Constant array of cardinal produces error ‘Constant expression violates subrange bounds” – Stack Overflow:
const dynamic arrays.In this case, Delphi XE6 and below regard the [...] construct for constants as a set of Byte of which the maximum value is 255.
So this already fails with E1012 Constant expression violates subrange bounds, even though 257 perfectly fits the subrange of Cardinal:
const CardinalArray: array of Cardinal = [257];
The documentation (which has not changed since Delphi 2007) puts you in a totally different direction: [WayBack] x1012: Constant expression violates subrange bounds
x1012: Constant expression violates subrange boundsThis error message occurs when the compiler can determine that a constant is outside the legal range. This can occur for instance if you assign a constant to a variable of subrange type.
program Produce; var Digit: 1..9; begin Digit := 0; (*Get message: Constant expression violates subrange bounds*) end. program Solve; var Digit: 0..9; begin Digit := 0; end.
The alternative is to use a non-dynamic array that uses parenthesis instead of square brackets for initialisation:
const CardinalArray: array[0..0] of Cardinal = (257);
Const initialisation of dynamic arrays only made a tick mark on the box in [Archive.is] What’s New in Delphi and C++Builder XE7 – RAD Studio: String-Like Operations Supported on Dynamic Arrays, but in fact this code works in Delphi XE7 and up just fine:
program Cardinals; {$APPTYPE CONSOLE} uses System.SysUtils; const CardinalArray: array of Cardinal = [257]; // fails until Delphi XE6 with "E1012 Constant expression violates subrange bounds" const ANSICOLORS: array of Cardinal = [ $000000,//0 $800000,//1, compilation error starts with this value $008000,//2 $808000,//3 $000080,//4 $800080,//5 $008080,//6 $D0D0D0,//7 $3F3F3F,//8 $FF0000,//9 $00FF00,//A $FFFF00,//B $0000FF,//C $FF00FF,//D $00FFFF,//E $FFFFFF];//F var AnsiColor: Cardinal; begin try for AnsiColor in AnsiColors do Writeln(Format('$%6.6x', [AnsiColor])); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.Output:
$000000 $800000 $008000 $808000 $000080 $800080 $008080 $D0D0D0 $3F3F3F $FF0000 $00FF00 $FFFF00 $0000FF $FF00FF $00FFFF $FFFFFF
Note that dynamic arrays are unlike regular arrays, which for instance means that nesting them can get you into a different uncharted territory when using multiple dimensions.
Unlike an array, a dynamic array has notice of length. Which means it needs extra memory for it.
So where regular multi-dimensional arrays are blocks of memory. Multi-dimensional dynamic arrays are a dynamic array on each dimension level, which means extra length keeping, and the seemingly odd Copy behaviour described in [WayBack] Things that make you go ‘urgh’… | Delphi Haven:
What’s the flaw in this test code?
1234567891011121314151617181920212223programProject1;{$APPTYPE CONSOLE}varArr1, Arr2:arrayofarrayofInteger;I, J:Integer;beginSetLength(Arr1,5,5);forI :=0to4doforJ :=0to4doArr1[I, J] := I * J;Arr2 := Copy(Arr1);forI :=0to4doforJ :=0to4doifArr2[I, J] <> Arr1[I, J]thenbeginWriteLn('Nope');Break;end;Write('Press ENTER to exit...');ReadLn;end.
with these comments
Rudy Velthuis:
Dynarrays are single-dimensional. One can get the illusion of multi-dimensionality because the Delphi syntax lets you access them using a[5,6] syntax, and SetLength takes more than one dimension parameter, and indeed, the docs even mention multi-dimensional, but that doesn’t change anything. You don’t have a multi-dimensional dynarray, you have a dynarray than contains other dynarrays. Each of these is one-dimensional. IOW, you don’t have one array, you have a cluster of dynarrays.
Copy() handles dynarrays. These are one-dimensional, so it only does one dimension (what else?). IOW, the behaviour is correct and actually well known.
Franćois:
I’m with you Chris. I don’t think this is “well known”, maybe because mono-dimensional dynamic arrays are probably used much more than multidimensional ones.
And also, the documentation is blaringly silent on this behavior. (credit to DelphiBasics to mention it: http://www.delphibasics.co.uk/RTL.asp?Name=Array)
The more visibility it gets, the less bugs we’ll have to deal with.IMO, I don’t see why “copy” would not behave recursively and copy each sub-array as well. It seems that it is the intuitive behavior people tend to expect in the 1st place. (either nothing at all like Arr1:=Arr2, or a full recursive copy)
But since it’s been like that for some time, I doubt it can change for compatibility reasons (breaking code relying explicitly on this behavior).Chris:
Thanks for the support! On my reading, the help strongly implies the behaviour I was expecting, and therefore, implies the actual behaviour to be a bug. Specifically, the entry for Copy (http://docwiki.embarcadero.com/VCL/en/System.Copy) includes the line:
Note: When S is a dynamic array, you can omit the Index and Count parameters and Copy copies the entire array.
What could ‘the entire array’ mean? According to Rudy, this can’t mean more than one dimension because dynamic arrays aren’t multidimensional. And yet, the Delphi Language Guide talks of ‘multidimensional dynamic arrays’ quite clearly (http://docwiki.embarcadero.com/RADStudio/en/Structured_Types#Multidimensional_Dynamic_Arrays). See also the docs for SetLength (http://docwiki.embarcadero.com/VCL/en/System.SetLength).
–jeroen
Posted in Delphi, Development, History, Software Development, Undocumented Delphi | Leave a Comment »
Posted by jpluimers on 2021/03/02
Today exactly 20 years ago, a futurist indicated “The Internet will not become a mass medium”.
Source: [WayBack] littlewisehen on Twitter: “Also sprach der Zukunftsforscher… 😂 https://t.co/taNRUxZD3S”
Via:
Thomas also made this great (German) observation:
2001 war vielfach noch Modem und ISDN angesagt, Flatrates waren gerade wieder abgeschafft worden, DSL gab es in machen Gegenden, war bei 2 Mbit aber mehr als doppelt so teuer wie heute 16 Mbit. Erinnert sich noch jemand an die unsäglichen AOL-CDs, die allen Zeitschriften beilagen?
Es gab noch keine “sozialen” Netzwerke und von mobilem Internet hat man nur geträumt. Selbst dumme Handys waren noch nicht so weit verbreitet wie heute Smartphones, und es kostete richtig Geld, eines anzurufen.Das ist noch keine 20 Jahre her, aber ich komme mir gerade vor, als ob ich die Zeit des Schwarz-Weiß-Fernsehens beschriebe.
Google Translate actually does a halfway decent job on that (see below) which I’ve edited to this:
2001 was in many cases still the era of modem and ISDN. Flat rates had just been abolished again, there was DSL available in some areas, but at 2 Mbit was more than twice as expensive as todays 16Mbit. Does anyone remember the inexpressible AOL CDs that came with all the magazines?
There were no “social” networks and you could only dream of mobile Internet. Even dumb phones were not as widespread as smartphones are today, and it costed real money to call a mobile phone.That was only 20 years, but it just feels as describing black and white television.
Unedited Google Translate:
Posted in History | Leave a Comment »
Posted by jpluimers on 2021/02/11
I totally agree with Nick Craver “I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…”.
A little event in the early 1990s made me cautious whenever I see environment variables in use.
One of my clients had a network that had to be separated into three logical areas: one for workstations communicating with a certain server and some equipment, and another for a different server and other equipment, and finally a bunch of semi-local workstations that did some peer-to-peer and specialised equipment communication.
For that era, this was a LOT of stuff to manage.
Since users always were working from the same computers, and there was very little overlap between the areas, I created a bunch of login scripts. Since this was Novell NetWare 3.x era, you only had default, system and user login scripts (see [WayBack] NetWare 3 Login Script Fundamentals), of which only system+default or system+user could be combined. No groups scripts yet (:
So I introduced an environment variable NETWORK that would hold the kind of logical network.
Boy was I surprised that a few days later, the head of administration came to me with a problem: one of his administration programs – despite no documentation mentioning anything about such a feature – suddenly asked for a license!
A few hours of phone calls and trying later, we found the culprit: that software had an undocumented feature: when the NETWORK environment variable was set, it assumed a large corporate, with a very special license feature.
That was the day, I started to be wary of environment variables.
The workaround was simple: have the program being started with a batch file, temporarily clean the NETWORK environment variable, then run the application, and finally restore the environment variable.
Inspired by two tweets I got within a few days time:
Maybe I’m a minority opinion the way things are going, but I absolutely hate environmental variables for configuration. They’re brittle, they’re ambient, they can be changed and FUBAR any known state underneath you, they’re an attack vector, just…ugh. I do not care for them.The most common answer I get on “why?” is “that’s the cross-platform way, everyone supports it”.Okay, yeah sure…I agree that we’re at the least common denominator. My issue is settling for that. I don’t think most things should. We can do far better. Options already exist.
I love the way .NET Core does this – IOptions is very pluggable and one of my favorite API designs because it fits so many scenarios, including complex deployment and multi-tenant things we have here.It’s defaulting straight to “make it an environmental variable” that gets me.
I’ve seen so bugs where a thing works forever but stops because some sysadmin somewhere deployed a GPO that sets an environmental variable deployed to many machines that silently changed behavior of apps that haven’t been deployed in years, just happens on restart and…ugh.That’s just one example, there are many.“It works on my machine” is a problem. Environmental variables magnify that problem immensely. They’re a maybe permanent, maybe ephemeral, maybe local, maybe global external state that adds more to control, break, reason about, and debug.
“Why does this app work, but this one doesn’t?”“After 2 days of debugging we found out this one runs as account X with variables Y and it has the SDK path correctly set, the other one didn’t have that variable”
“…I quit.”
–jeroen
Posted in History, Power User, Security | Leave a Comment »
Posted by jpluimers on 2021/01/18
From a while back: [WayBack] This week, a mini-demo of the mini-assembler found inside Woz’ monitor inside Apple II Integer Basic. CALL –151 F666G … – mos6502 – Google+
This week, a mini-demo of the mini-assembler found inside Woz’ monitor inside Apple II Integer Basic.
CALL –151
F666G
You can find reconstructed sources in Jeff Tranter’s repo here:
https://github.com/jefftranter/6502/tree/master/asm/Apple%5D%5BMonitor
where we see credits to Steve Wozniak and Allen Baum. But in this oral history it seems the assembler was Baum’s work:
“Baum: So it was brute force, very simple and fit into 256 bytes if you already had the 256-byte disassembler.”
– https://youtu.be/wN02z1KbFmY?t=3941
Anyhow, one page of code – or two – is very impressive!For more info, try searching for F666G! (We wonder at this memorable address – the Apple I price was $666.)
Related:
go.com program to start a program at 0x100 that was already in memory)–jeroen
Posted in 6502, Apple, Apple I, Apple ][, History | Leave a Comment »
Posted by jpluimers on 2021/01/04
From the [WayBack] RetroMacCast : RMC Episode 433: Clamshell G4 iBook the most interesting pieces to me were these:
–jeroen
Posted in 6502, Apple, Apple ][, History, Power User | Leave a Comment »
Posted by jpluimers on 2020/12/21
In 2019 instrueerde [WayBack] Axender B.V. (@AxenderBV) | Twitter haar bezorgers om langs alle deuren te gaan, ook die in Amsterdam geen JA-JA sticker hebben.
Die bezorger hoef je dan dus geen fooi te geven, want je krijgt geen folders.
Axender bezorgt ook incidenteel de City krant: bij ons in Amsterdam 1 keer in 2018.
–jeroen
Gerelateerd:
Posted in About, History, Personal | Leave a Comment »
Posted by jpluimers on 2020/12/07
Reminder to self: see if I ever can resurrect my old BBS and FidoNet node that was based on at least:
Maybe a good place to start: [WayBack] Running BBS Door Games on Windows 10 with GameSrv, DOSBox, plus telnet fun with WSL – Scott Hanselman
I already wrote a few times about me being on Fidonet, and BITNET in the late 1980s:
A few email addresses I have been using in that era:
A tag-line from me in that era (I blanked out the phone number as it now belongs to someone else):
o _ _ _ _ _ voice: +31-2522-XXXXX (19:00-22:00 UTC)
/ (_' | (_) (_' | | snail: P.S.O.
__/ attn. Jeroen W. Pluimers
P.O. Box 266
jeroenp@rulfc1.LeidenUniv.nl 2170 AG Sassenheim
jeroen_pluimers@f521.n281.z2.fidonet.org The Netherlands
Related:
–jeroen
Posted in BBS, dial-up modems, FidoNet, History, MS-DOS, Power User, Windows | Leave a Comment »
Posted by jpluimers on 2020/12/04
December thoughts: [WayBack] Why is “finite” in “infinite” pronounced differently than plain “finite”?… – Jeroen Wiert Pluimers – Google+
Why is “finite” in “infinite” pronounced differently than plain “finite”?
As a partially word-blind person, those differences make natural languages very hard for me to grasp.
Especially because Dutch “eindig” is pronounced the same in “oneindig” (and German “endlich” the same in “unendlich“)
My guess is that it’s easier to say. They were probably pronounced the same 500 years ago but over time it became easier (lazier) to say 3 short vowels (because they are all the same sound) versus 1 short and 2 long. I’d be very interested in hearing what the old English pronunciation sounded like.
Steven Pinker has a great talk on irregular verbs. In a nutshell certain words when put into a typical sentence are too much of a tongue twister. If the word or phrase is used enough people develop shortcuts to make them easier to say. The interesting aspect that he identified is that if some word falls out of common usage the pronunciation becomes regular again. People forget that they can say it the easier way. His talk is about irregular verbs, but the concept is much more general than that.![]()
Two great explanations, which both boil down to the truth and fact that people are lazy and languages adapt over time.
English spelling is from the 15th century, but pronunciation has changed.
Norwegian has tried to update their spelling to be closer to the actual use, and also removed duplicate “spelling” of the same sounds.
Some languages are sponges, and fill up with words from other languages, and either keep the sounds or change them a little, even if they don’t conform to their own language. Others, like Icelandic, create brand new words for everything.
–jeroen
Posted in History, LifeHacker, Power User | Leave a Comment »