{ "version" : "https://jsonfeed.org/version/1.1", "title" : "The Boston Diaries", "home_page_url" : "https://boston.conman.org/", "feed_url" : "https://boston.conman.org//index.json", "description" : "The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”", "user_comment" : "twenty-three skidoo", "icon" : "http://www.conman.org/people/spc/about/1998/0301.gif", "favicon" : "http://www.conman.org/people/spc/about/1998/0301.gif", "authors" : [ { "name" : "Sean Conner" } ], "language" : "en-US", "items" : [ { "id" : "https://boston.conman.org/2024/03/01.1", "url" : "https://boston.conman.org/2024/03/01.1", "title" : "The speed of Microsoft's BASIC floating point routines", "content_html" : "
I was curious about how fast Microsoft's BASIC floating point routines were.\nThis is easy enough to test,\nnow that I can time assembly code inside the assembler.\nThe code calculates -2π3/3! using Color BASIC routines,\nIEEE-754 single precision and double precision.
\n\nFirst, Color BASIC:
\n\n\n\t.tron\ttiming\nms_fp\t\tldx\t#.tau\n\t\tjsr\tCB.FP0fx\t; FP0 = .tau\n\t\tldx\t#.tau\n\t\tjsr\tCB.FMULx\t; FP0 = FP0 * .tau\n\t\tldx\t#.tau\n\t\tjsr\tCB.FMULx\t; FP0 = FP0 * .tau\n\t\tjsr\tCB.FP1f0\t; FP1 = FP0\n\t\tldx\t#.fact3\n\t\tjsr\tCB.FP0fx\t; FP0 = 3!\n\t\tjsr\tCB.FDIV\t\t; FP0 = FP1 / FP0\n\t\tneg\tCB.fp0sgn\t; FP0 = -FP0\n\t\tldx\t#.answer\n\t\tjsr\tCB.xfFP0\t; .answer = FP0\n\t.troff\n\t\trts\n\n.tau\t\tfcb\t$83,$49,$0F,$DA,$A2 \n.fact3\t\tfcb\t$83,$40,$00,$00,$00 \n.answer\t\trmb\t5\n\t\tfcb\t$86,$A5,$5D,$E7,$30\t; precalculated result\n\n\n\n
I can't use the .FLOAT
directive here since that only supports either the Microsoft format or IEEE-754 but not both.\nSo for this test,\nI have to define the individual bytes per float.\nThe last line is what the result should be\n(by checking a memory dump of the VM after running).\nAlso,\n.tao
is 2π,\njust in case that wasn't clear.\nThis ran in 8,742 cycles,\ntaking 2,124 instructions and 4.12 cycles per instruction\n(I modified the assembler to record this additional information).
Next up,\nIEEE-754 single precision:
\n\n\n\t.tron\ttiming\nieee_single\tldu\t#.tau\n\t\tldy\t#.tau\n\t\tldx\t#.answer\n\t\tldd\t#.fpcb\n\t\tjsr\tREG\n\t\tfcb\tFMUL\t; .answer = .tau * .tau\n\n\t\tldu\t#.tau\n\t\tldy\t#.answer\n\t\tldx\t#.answer\n\t\tldd\t#.fpcb\n\t\tjsr\tREG\n\t\tfcb\tFMUL\t; .answer = .answer * .tau\n\n\t\tldu\t#.answer\n\t\tldy\t#.fact3\n\t\tldx\t#.answer\n\t\tldd\t#.fpcb\n\t\tjsr\tREG\n\t\tfcb\tFDIV\t; .answer = .answer / 3!\n\n\t\tldy\t#.answer\n\t\tldx\t#.answer\n\t\tldd\t#.fpcb\n\t\tjsr\tREG\n\t\tfcb\tFNEG\t; .answer = -.answer\n\t.troff\n\t\trts\n\n.fpcb\t\tfcb\tFPCTL.single | FPCTL.rn | FPCTL.proj\n\t\tfcb\t0\n\t\tfcb\t0\n\t\tfcb\t0\n\t\tfdb\t0\n\n.tau\t\t.float\t6.283185307\n.fact3\t\t.float\t3!\n.answer\t\t.float\t0\n\t\t.float\t-(6.283185307 ** 3 / 3!)\n\n\n\n
The floating point control block (.fpcb
) configures the MC6839 to use single precision,\nnormal rounding and projective closure\n(not sure what that is,\nbut it's the default value).\nAnd it does calculate the correct result.\nIt's amazing that code written 42 years ago for an 8-bit CPU works flawlessly.\nWhat is isn't is fast.\nThis code took 14,204 cycles over 2,932 instructions (average 4.84 cycles per instruction).
The higher than average cycle type could be due to position independent addressing modes,\nbut I'm not entirely sure what it's doing to take nearly twice the time.\nThe ROM does use the IEEE-754 extended format (10 bytes) internally,\nwith more bit shifts to extract the exponent and mantissa,\nbut twice the time?
\n\nPerhaps it's code to deal with ±∞ and NaNs.
\n\nThe IEEE-754 double precision is the same,\nexcept for the floating point control block configuring double precision and the use of .FLOATD
instead of .FLOAT
;\notherwise the code is identical.\nThe result,\nhowever,\nisn't.\nIt took 31,613 cycles over 6,865 instructions (average 4.60 cycles per instruction).\nAnd being twice the size,\nit took nearly twice the time as single precision,\nwhich is expected.
The final bit of code just loads the ROMs into memory,\nand calls each function to get the timing:
\n\n\n\t\torg\t$2000\n\t\tincbin\t\"mc6839.rom\"\nREG\t\tequ\t$203D\t; register-based entry point\n\n\t\torg\t$A000\n\t\tincbin\t\"bas12.rom\"\n\n\t.opt\ttest\tprot\trw,$00,$FF\t; Direct Page for BASIC\n\t.opt\ttest\tprot\trx,$2000,$2000+8192 ; MC6839 ROM\n\t.opt\ttest\tprot\trx,$A000,$A000+8192 ; BASIC ROM\n\n\t.test\t\"BASIC\"\n\t\tlbsr\tms_fp\n\t\trts\n\t.endtst\n\n\t.test\t\"IEEE-SINGLE\"\n\t\tlbsr\tieee_single\n\t\trts\n\t.endtst\n\n\t.test\t\"IEEE-DOUBLE\"\n\t\tlbsr\tieee_double\n\t\trts\n\t.endtst\n\n\n\n
Really,\nthe only surprising thing here was just how fast Microsoft BASIC was at floating point.
\n", "date_published" : "2024-03-09T22:05:12Z", "tags" : [ "Microsoft BASIC floating point","IEEE-754 floating point","floating point on 8bit CPU","MC6839" ] } ,{ "id" : "https://boston.conman.org/2024/02/28.1", "url" : "https://boston.conman.org/2024/02/28.1", "title" : "Converting IEEE-754 floating point to Color BASIC floating point", "content_html" : "I'm still playing around with floating point on the 6809—specifically,\nsupport for floating point for the Color Computer.\nThe format for floating point for Color BASIC\n(written by Microsoft)\npredates the IEEE-754 Floating Point Standard by a few years and thus,\nisn't quite compatible.\nIt's close,\nthough.\nIt's defined as an 8-bit exponent,\nbiased by 129,\na single sign bit\n(after the exponent)\nand 31 bits for the mantissa\n(the leading one assumed).\nIt also does not support ±∞ nor NaN.\nThis differs from the IEEE-754 single precision that uses a single sign bit,\nan 8-bit exponent biased by 127 and 23 bits for the mantissa\n(which also assumes a leafing one) and support for infinities and NaN.\nThe IEEE-754 double precision uses a single sign bit,\nan 11-bit exponent biased by 1023 and 52 bit for the mantissa\n(leading one assumed)\nplus support for infinities and NaN.
\n\nSo the Color BASIC is about halfway between single precision and double precision.\nThis lead me to use IEEE-754 double precision for the Color Computer backend\n(generating an error for inifinities and NaN)\nthen massaging the resulting double into the proper format.\nI double checked this by finding some floating point constants in the Color BASIC ROM as shown in the book Color BASIC Unravelled II, \n(available on the Computer Computer Archives),\nlike this table:
\n\n\n4634\t\t\t\t* MODIFIED TAYLOR SERIES SIN COEFFICIENTS\n4635\tBFC7 05\t\t\tLBFC7\tFCB\t6-1\t\t\tSIX COEFFICIENTS\n4636\tBFC8 84 E6 1A 2D 1B\tLBFC8\tFCB\t$84,$E6,$1A,$2D,$1B\t* -((2*PI)**11)/11!\n4637\tBFCD 85 28 07 FB F8\tLBFCD\tFCB\t$86,$28,$07,$FB,$F8\t* ((2*PI)**9)/9!\n4638\tBFD2 87 99 68 89 01\tLBFD2\tFCB\t$87,$99,$68,$89,$01\t* -((2*PI)**7)/7!\n4639\tBFD7 87 23 35 DF E1\tLBFD7\tFCB\t$87,$23,$35,$DF,$E1\t* ((2*PI)**5)/5!\n4640\tBFDC 86 A5 5D E7 28\tLBFDC\tFCB\t$86,$A5,$5D,$E7,$28\t* -((2*PI)**3)/3!\n4641\tBFE1 83 49 0F DA A2\tLBFE1\tFCB\t$83,$49,$0F,$DA,$A2\t* 2*PI\n\n\n\n
Then using the byte values to populate a variable and printing it inside BASIC\n(this is the expression -2π3/3!):
\n\n\nX=0 ' CREATE A VARIABLE\nY=VARPTR(X) ' GET ITS ADDRESS\nPOKE Y,&H86 ' AND SET ITS VALUE\nPOKE Y+1,&HA5 ' THE HARD WAY\nPOKE Y+2,&H5D\nPOKE Y+3,&HE7\nPOKE Y+4,&H28\nPRINT X ' LET'S SEE WHAT IT IS\n-41.3417023\n\n\n\n
Then using that to create a floating point value:
\n\n\n\torg\t$1000\n\t.float\t-41.3417023\n\tend\n\n\n\n
Checking the resulting bytes that were generated:
\n\n\n | FILE ff.a\n 1 | org $1000\n1000: 86A55DE735 2 | .float -41.3417023\n 3 | end\n\n\n\n
And adjusting the floating point constant until I got bytes that matched:
\n\n\n | FILE ff.a\n 1 | org $1000\n1000: 86A55DE728 2 | .float -41.341702110\n 3 | end\n\n\n\n
I figure it's “close enough.”\nThe parsing code in the Color BASIC ROM is old and predates the IEEE-754 floating point standard,\nso a few different digits at the end I think is okay.
\n\nAs a final check,\nI wrote the following bit of code to calculate and display -2π3/3!,\ndisplay the pre-calculated result,\nas well as display the pre-calculated value of 2π:
\n\n\n\t\tinclude\t\"Coco/basic.i\"\n\t\tinclude\t\"Coco/dp.i\"\n\nCB.FSUBx\tequ\t$B9B9\t; FP0 = X - FP0\t; addresses for\nCB.FSUB\t\tequ\t$B9BC\t; FP0 = FP1 - FP0\t; these routines \nCB.FADDx\tequ\t$B9C2\t; FP0 = X + FP0\t; from\nCB.FADD\t\tequ\t$B9C5\t; FP0 = FP1 + FP1\t; Color BASIC Unravelled II\nCB.FMULx\tequ\t$BACA\t; FP0 = X * FP0\nCB.FMUL\t\tequ\t$BAD0\t; FP0 = FP0 * FP1\nCB.FDIVx\tequ\t$BB8F\t; FP0 = X / FP0\nCB.FDIV\t\tequ\t$BB91\t; FP0 = FP1 / FP0\n\nCB.FP0fx\tequ\t$BC14\t; FP0 = X\nCB.xfFP0\tequ\t$BC35\t; X = FP0\nCB.FP1f0\tequ\t$BC5F\t; FP1 = FP0\nCB.FP0txt\tequ\t$BDD9\t; result in X, NUL terminated\n\n\t\torg\t$4000\nstart\t\tldx\t#tau\t\t; point to 2*pi\n\t\tjsr\tCB.FP0fx\t; copy to FP0\n\t\tldx\t#tau\t\t; 2PI * 2PI\n\t\tjsr\tCB.FMULx\n\t\tldx\t#tau\t\t; 2PI * 2PI * 2PI\n\t\tjsr\tCB.FMULx\n\t\tjsr\tCB.FP1f0\t; copy fp acc to FP1\n\t\tldx\t#fact3\t\t; point to 3!\n\t\tjsr\tCB.FP0fx\t; copy to FP0\n\t\tjsr\tCB.FDIV\t\t; FP0 = FP1 / FP0\n\t\tneg\tCB.fp0sgn\t; negate result by flippping FP0 sign\n\t\tjsr\tCB.FP0txt\t; generate string\n\t\tbsr\tdisplay\t\t; display on screen\n\n\t\tldx\t#answer\t\t; point to precalculated result\n\t\tjsr\tCB.FP0fx\t; copy to FP0\n\t\tjsr\tCB.FP0txt\t; generate string\n\t\tbsr\tdisplay\t\t; display\n\n\t\tldx\t#tau\t\t; now display 2*pi\n\t\tjsr\tCB.FP0fx\t; just to see how close\n\t\tjsr\tCB.FP0txt\t; it is.\n\t\tbsr\tdisplay\n\t\trts\n\ndisplay.char\tjsr\t[CHROUT]\t; display character\ndisplay\t\tlda\t,x+\t\t; get character\n\t\tbne\t.char\t\t; if not NUL byte, display\n\t\tlda\t#13\t\t; go to next line\n\t\tjsr\t[CHROUT]\n\t\trts\n\ntau\t\t.float\t6.283185307\nfact3\t\t.float\t3!\nanswer\t\t.float\t-(6.283185307 ** 3 / 3!)\n\n\t\tend\tstart\n\n\n\n
The results were:
\n\n\n-41.3417023\n-41.3417023\n 6.23418531\n\n\n\n
The calculation results in -41.3417023 and the direct result stored in answer
also prints out -41.3417023,\nso that matches and it reinforces my approach to this nominally right.
But I think Microsoft had issues with either generating some of the floating point constants for the larger terms,\nor transcribing the byte values of the larger terms.\nTake for instance -2π11/11!.\nThe correct answer is -15.0946426,\nbut the bytes in the ROM define the constant -14.3813907,\na difference of .7.\nAnd it's not like Color BASIC can't calculate that correctly—when I typed in the expression by hand,\nit was able to come up with -15.0946426.
\n\nOr it could be that Walter K. Zydhek, the\nauthor of Color BASIC Unravelled II,\nis wrong in his interpretation of the expressions used to generate the values,\nor his interpretation of what the values are used for.\nI'm not sure who is at fault here.
I was wrong about the authorship of Color BASIC Unravelled II.\nIt was not Walter K. Zydhek,\nbut some unknown author of Spectral Associates,\na company that is no longer in business.\nAll Zydhek did was to transcribe a physical copy of the book (which is no longer available for purchase anywhere) into a PDF and make it available.
\n\n“Oh! Now what?”
\n\n“Sir,\nsee the lit sign up there?\nYou cannot turn right.”
\n\n“But did you not see the car right in front of me turning right?”
\n\n“Sir,\nif a person jumped off a bridge,\nwould you follow?”
\n\n“Yes.”
\n\n“You must be very smart then.”
\n\n“And selective enforcement of the laws leads to distrust of the police.”
\n\n“Sir—”
\n\n“Oh look! The ‘No Right Turn’ sign is off now!\nGotta go!\nBye!”
\n\n“I don't think it's wise to taunt the poice like that.”
\n\n“Down with the Man! Power to the people! Yo!”
\n", "date_published" : "2024-02-15T00:21:27Z", "tags" : [ "daily life","cops","police","police interaction" ] } ,{ "id" : "https://boston.conman.org/2024/02/11.1", "url" : "https://boston.conman.org/2024/02/11.1", "title" : "An extensible programming language", "content_html" : "A few days ago I wrote about adding a factorial operator to my assembler,\nand I noted that I knew not of any other languages that had such a feature.\nSo imagine my surprise as I'm reading about XL \n(via Lobsters)\nand the second example is factorial!\nNot only that,\nbut that was an example of extending the language itself!\nThe last time I was this excited about software was reading about Synthesis OS,\na JIT-based operating system where you could create your own system calls.
\n\nHow it handles precedence is interesting.\nIn my assembler,\nI have left or right associativity as an explicit field,\nwhereas in XL,\nit's encoded in the precedence level itself—even if its left,\nodd if its right.\nI'm not sure how I feel about that.\nOn the one hand it feels nice and it's one less field to carry around;\non the other,\nbeing explicit as I did makes it clear if something is left or right.\nBut on the gripping hand,\nit sounds like matching precedence on a left and right operator could lead to problems,\nso I still may have an explicitness problem.
\n\nBut I digress.
\n\nIt's a very simple language with only one keyword “is” and a user-definable precedence table.\nThe parser generates a parse tree of only eight types,\nfour leaf nodes (integer, real, text, name (or symbol))\nand four non-leaf nodes (prefix, infix, postfix and block).\nAnd from there,\nyou get XL.
\n\nThis is something I definitely want to look into.
\n", "date_published" : "2024-02-12T02:33:08Z", "tags" : [ "XL","extensible language","parsers","compilers","language design" ] } ,{ "id" : "https://boston.conman.org/2024/02/07.1", "url" : "https://boston.conman.org/2024/02/07.1", "title" : "Instead of “write-only memory” assembly support, how about floating point support?", "content_html" : "You might think it odd to add support for floating point constants for an 8-bit CPU,\nbut Motorola did development on the MC6839 floating point firmware for the MC6809,\nan 8K ROM of thread-safe, position-independent 6809 code that implements the IEEE Standard for Floating-Point Arithmetic.\nIt was never formally released by Motorola as a product,\nbut from what I understand,\nit was released later under a public domain license.\nAt the very least,\nit's quite easy to MC6839 find both the ROM image and the source code on the Intarwebs.\nSo that's one reason.
\n\nAnother reason is that the Color Computer BASIC supports floating point operations,\nand while not IEEE-754,\nas it was written before the IEEE-754 standard become a standard,\nit still floating point,\nand there are only minor differences between it and the current standard,\nnamely the exponent bias,\nnumber of fractional bits supported,\nand where the sign bit is stored.\nIt really comes down to some bit manipulations to massage a standard float into the Color Computer BASIC float format.\nThere are some differences,\nbut the differences are small\n(literally,\non the scale of 0.0000003)\nprobably due to parsing differences,\nand small enough that it should be “good enough.”\nEspecially since the Color Computer BASIC float format doesn't support infinity or NaN.
\n\nSo if you specify a backend other than the rsdos
backend,\nyou get IEEE-754,\nand if you do specify rsdos
as a backend,\nyou get the Color Computer BASIC float format.
And yes,\nI added support for floating point expressions\n(but not for the test backend—I'm still thinking on how to support it),\nand one interesting feature I added is the factorial operator “!”.\nFactorials are used in Talor series,\nwhich the Color Computer BASIC uses for the sin()
function,\nso I can literally write:
\n\t; Oh! '**' is exponentiation by the way!\ntaylor_series\t.float\t-((2 * 3.14159265358979323846) ** 11) / 11!\n\t\t.float\t ((2 * 3.14159265358979323846) ** 9) / 9!\n\t\t.float\t-((2 * 3.14159265358979323846) ** 7) / 7!\n\t\t.float\t ((2 * 3.14159265358979323846) ** 5) / 5!\n\t\t.float\t-((2 * 3.14159265358979323846) ** 3) / 3!\n\t\t.float\t 2 * 3.14159265358979323846\n\n\n\n
and have it generate the correct values.\nI personally don't know of any language that has a factorial operator\n(maybe APL?\nI don't know).
\n\nI think I'm having more fun writing the assembler than I am writing assembly code.
\n", "date_published" : "2024-02-08T04:15:29Z", "tags" : [ "programming","overengineered 6809 assembler","A09","floating-point support","IEEE-754","MC6839","Taylor series" ] } ,{ "id" : "https://boston.conman.org/2024/02/06.2", "url" : "https://boston.conman.org/2024/02/06.2", "title" : "Okay! I'll answer your question, LinkedIn. Also, Orange Site! Orange Site! Orange Site!", "content_html" : "Today's “you're one of the few experts invited to add this collaborative article” from LinkedIn is\n“How do you become a senior application developer?”\nMy answer?\nStay in a programming job for three years.\nBoom!\nYou're a senior application developer.\nI know,\nI know,\nthat's a big ask these days when everybody is jumping ship every two years.\nBut hey,\nif you want to be a “senior application developer,”\nyou got to make sacrifices.
\n\nOh,\nand the title to today's post?\nI found out that LinkedIn really liked when I mentioned the Orange Site in the title of my post.\nAlmost two orders of magnitude more.\nSo I'm doing a test to see if I can game the system there.
\n", "date_published" : "2024-02-07T02:47:36Z", "tags" : [ "SEO","gaming the system","LinkedIn","Orange Site","Hacker News","how you become a senior application developer" ] } ,{ "id" : "https://boston.conman.org/2024/02/06.1", "url" : "https://boston.conman.org/2024/02/06.1", "title" : "So you want to amplify my SEO", "content_html" : "\n\n\n\n\n
\n\n- From
- Krystal XXXXXXX <XXXXXXXXXXXXXXXXXXXX@gmail.com>
\n- To
- sean@conman.org
\n- Subject
- Amplify Your SEO with Strategic Link Inserts
\n- Date
- Wed, 7 Feb 2024 01:16:35 +0300
\nHi Content Team,
\n\nIt’s Krystal XXXXXXX here from Next Publisher, your next potential partner\nin digital storytelling. We're thrilled about the idea of featuring both\nguest posts and link insertions on your dynamic website.
\n\nWe would like to know your fee structure for hosting guest posts and link\ninsertions. Our team aims to create compelling content that is tailored to\nyour site’s audience and enhances your overall content strategy.
\n\nA quick note: this initial email is only for starting our dialogue. All\nmore detailed communications, including agreements and transactions, will\nbe carried out through our official Next Publisher email.
\n\nWe admire the quality of your platform and are excited to explore how we\ncan work together for mutual benefit.
\n\nLooking forward to your prompt reply.
\n\nWarm wishes,
\n\nKrystal XXXXXXX\n\n\n
Hello Krystal.
\n\nSince you neglected to include a link\n(in an email sent as HTML no less!)\nit's hard for me judge the value Next Publisher will provide for my site,\nso I'm going to have to adjust my prices accordingly.\nMy fee for both guest posts and link insertions is $10,000 (US) per.\nSo if a guest post also includes a link insertion,\nthat would be a total of $20,000 (US).\nIf I'm going to be whoring selling out what Google Page Rank I have,\nit's going to cost.
I look forward to hearing back from you.
\n\nSean.
\n\n\n", "date_published" : "2024-02-07T00:09:01Z", "tags" : [ "spam","email","email spam","Next Publisher","selling out" ] } ,{ "id" : "https://boston.conman.org/2024/02/05.1", "url" : "https://boston.conman.org/2024/02/05.1", "title" : "The difficulties in supporting “write-only memory” in assembly", "content_html" : "When I last wrote about this,\nI had one outstanding problem with static analysis of read-only/write-only memory,\nand that was with hardware that could be input or output only.\nIt was only after I wrote that that I realized the solution—it's the same as a hardware register having different semantics on read vs. write—just define two labels with the semantics I want.\nSo for the MC6821,\nI could have:
\n\n\n\t\torg\t$FF00\nPIA0.A\t\trmb/r\t1\t; read only\n\t\torg\t$FF00\nPIA0.Adir\trmb/w\t1\t; write only, to set the direction of each IO pin\nPIA0.Acontrol\trmb\t1\t; control for port A\n\n\n\n
So that was a non-issue.\nIt was then I started looking over some existing code I had to see how it might look.\nI didn't want to just jump into an implementation without some forethought,\nand I quickly found some issues with the idea by looking at my maze generation program.\nThe code in question initializes the required video mode\n(in this case 64×64 with four colors).\nStep one involves writing a particular value to the MC6821:
\n\n\n\t\tlda\t#G1C.PIA ; 64x64x4\n\t\tsta\tPIA1.B\n\n\n\n
So far so good. I can mark PIA1.B
as write-only\n(technically, it also has some input pins so I really can't,\nbut in theory I could).
Now,\nthe next bit requires some explaining.\nThere's another 3-bit value that needs to be configured on the MC6883,\nbut it's not as simple as writing the 3-bit value to a hardware register—each bit requires writing to a different address,\nand worse—it's a different address if the bit is 0 or 1.\nSo that's six different addresses required.\nIt's not horrible though—the addresses are sequential:
\n\nbit | 0/1 | address |
---|---|---|
V0 | 0 | $FFC0 |
V0 | 1 | $FFC1 |
V1 | 0 | $FFC2 |
V1 | 1 | $FFC3 |
V2 | 0 | $FFC4 |
V2 | 1 | $FFC5 |
Yeah,\nto a software programmer,\nhardware can be weird.\nTo set bit 0 to 0,\nyou do a write\n(and it does not matter what the value is)\nto address $FFC0
.\nIf bit 0 is 1,\nthen it's a write to $FFC1
.\nSo with that in mind,\nI have:
\n\t\tsta\tSAM.V0 + (G1C.V & 1<<0 <> 0)\n\t\tsta\tSAM.V1 + (G1C.V & 1<<1 <> 0)\n\t\tsta\tSAM.V2 + (G1C.V & 1<<2 <> 0)\n\n\n\n
OOh.\nYeah.
\n\nI wrote it this way so I wouldn't have to look up the appropriate value and write the more opaque\n(to me):
\n\n\n\t\tsta\t$FFC1\n\t\tsta\tSFFC2\n\t\tsta\t$FFC4\n\n\n\n
The expression (G1C.V & 1<<n <> 0)
checks bit n to see if it's set or not,\nand returns 0 (for not set) or 1 (for set).\nThis is then added to the base address for bit n,\nand it all works out fine. I can change the code for,\nsay, the 128×192 four color mode by using a different constant:
\n\t\tlda\t#G6C.PIA\n\t\tsta\tPIA1.B\n\t\tsta\tSAM.V0 + (G6C.V & 1<<0 <> 0)\n\t\tsta\tSAM.V1 + (G6C.V & 1<<1 <> 0)\n\t\tsta\tSAM.V2 + (G6C.V & 1<<2 <> 0)\n\n\n\n
But I digress.
\n\nThis is a bit harder to support.\nThe address being written is part of an expression,\nand only the label (defining the address) would have the read/write attribute associated with it.\nAt least,\nthat was my intent.\nI suppose I could track the read/write attribute by address,\nwhich would solve this particular segment of code.
\n\nAnd the final bit of code to set the address of the video screen\n(or frame buffer):
\n\n\n\t\tldx\t#SAM.F6\t\t; point to frame buffer address bits\n\t\tlda\tECB.grpram\t; get MSB of frame buffer\nmapframebuf\tclrb\n\t\tlsla\n\t\trolb\n\t\tsta\tb,x\t\t; next bit of address\n\t\tleax\t-2,x\n\t\tcmpx\t#SAM.F0\n\t\tbhs\tmapframebuf\n\n\n\n
Like the VDG Address Mode bits,\nthe bits for the VDG Address Offset have unique addresses,\nand because the VDG Address Offset has seven bits,\nthe address is aligned to a 512 byte boundary.\nHere,\nthe code loads the X
register with the address of the upper end of the VDG Address Offset,\nand the seven top most bits of the video address is sent,\none at a time,\nto the B
register,\nwhich is used as an offset to the X
register to set the appropriate address for the appropriate bit.\nSo now I would have to track the read/write attributes via the index registers as well.
That is not so easy.
\n\nI mean,\nhere,\nit could work,\nas the code is all in one place,\nbut what if instead it was:
\n\n\n\t\tldx\t#SAM.F6\n\t\tlda\tECB.grpram\n\t\tjsr\tmapframebuf\n\n\n\n
Or an even worse example:
\n\n\ncostmessage\tfcc/r\t\"A constant message\" ; read only text\nbuffer\t\trmb\t18\n\n\t\tldx\t#constmessage\n\t\tldy\t#buffer\n\t\tlda\t#18\n\t\tjsr\tmemcpy\n\n\n\n
The subroutine memcpy
might not even be in the same source unit,\nso how would the read/write attribute even be checked?\nThis is for static analysis,\nnot runtime.
I have one variation on the maze generation program that generates multiple mazes at the same time,\non the same screen\n(it's fun to watch)\nand as such,\nI have the data required for each “maze generator” stored in a structure:
\n\n\nexplorec\tequ\t0\t; read-only\nbacktrackc\tequ\t1\t; read-only\nxmin\t\tequ\t2\t; read-only\nymin\t\tequ\t3\t; read-only\nxstart\t\tequ\t4\t; read-only\nystart\t\tequ\t5\t; read-only\nxmax\t\tequ\t6\t; read-only\nymax\t\tequ\t7\t; read-only\nxpos\t\tequ\t8\t; read-write\nypos\t\tequ\t9\t; read-write\ncolor\t\tequ\t10\t; read-write\nfunc\t\tequ\t11\t; read-write\n\n\n\n
This is from the source code,\nbut I've commented each “field” as being “read-only” or “read-write.”\nThat's another aspect of this that I didn't consider:
\n\n\n\t\tlda\texplorec,x\t; this is okay\n\t\tsta\texplorec,x\t; this is NOT okay\n\n\n\n
Not only would I have to track read/write attributes for addresses,\nbut for field accesses to a structure as well.\nI'm not saying this is impossible,\nit's just going to take way more thought than I thought.\nI don't think I'll have this feature done any time soon …
\n", "date_published" : "2024-02-06T02:01:11Z", "tags" : [ "programming","overengineered 6809 assembler","A09","write-only memory" ] } ,{ "id" : "https://boston.conman.org/2024/02/02.4", "url" : "https://boston.conman.org/2024/02/02.4", "title" : "It should be obvious by now what day it is, but just in case", "content_html" : "I want to ensure everybody that yes,\nI intentionally made the previous three posts.\nAnd while they are similar,\nthey are not in fact,\nidentical.\nYou know,\nmuch like Ground Hog Day.
\n", "date_published" : "2024-02-03T02:30:49Z", "tags" : [ "Ground Hog Day","repeated posts" ] } ,{ "id" : "https://boston.conman.org/2024/02/02.3", "url" : "https://boston.conman.org/2024/02/02.3", "title" : "Making it to the Orange Site", "content_html" : "A previous post made it to Lobster only to later show up at the Orange Site.\nHow about that?
\n", "date_published" : "2024-02-03T02:30:42Z", "tags" : [ "Ground Hog Day","Hacker News","Lobsters","Orange Site" ] } ,{ "id" : "https://boston.conman.org/2024/02/02.2", "url" : "https://boston.conman.org/2024/02/02.2", "title" : "Making it to the Orange Site", "content_html" : "A previous post made it to Lobster only to later show up at the Orange Site.\nHow about that?
\n", "date_published" : "2024-02-03T02:30:35Z", "tags" : [ "Ground Hog Day","Hacker News","Lobsters","Orange Site" ] } ,{ "id" : "https://boston.conman.org/2024/02/02.1", "url" : "https://boston.conman.org/2024/02/02.1", "title" : "Making it to the Orange Site", "content_html" : "A previous post made it to Lobster only to later show up at the Orange Site.\nHow about that?
\n", "date_published" : "2024-02-03T02:30:29Z", "tags" : [ "Ground Hog Day","Hacker News","Lobsters","Orange Site" ] } ,{ "id" : "https://boston.conman.org/2024/01/31.4", "url" : "https://boston.conman.org/2024/01/31.4", "title" : "How much for the book? I don't think I paid that much for the computer", "content_html" : "Now,\nabout that Amiga Hardware Reference Manual link in my previous post—$577.99‽
\n\nSeriously‽
\n\nI know it's now a niche market,\nbut are there really people buying that book for almost $600?
\n\nGood Lord!
\n\n", "date_published" : "2024-02-01T05:23:56Z", "tags" : [ "Amiga","Amiga Hardware Reference Manual","insane Amazon prices for books" ] } ,{ "id" : "https://boston.conman.org/2024/01/31.3", "url" : "https://boston.conman.org/2024/01/31.3", "title" : "I know languages that have support for “read-only memory,” but what about “write-only memory?”", "content_html" : "I'm still hacking away on my overengineered 6809 assembler and one feature I've beem mulling over is a form of static access checking.\nI have byte-level access control when running tests but I'm thinking that adding some form of “assemble time checking” would also be good.\nI've been writing code hitting the hardware of the Color Computer,\nand there are semantics around hardware that I don't think many languages\n(or even assembler)\nsupport—write only memory!\nAs the Amiga Hardware Reference Manual states\n(only referenced here because it's a good example of what I'm talking about):
\n\n\n\n\n\n\n\nRegisters are either read-only or write-only. Reading a write-only register will trash the register.\nWriting a read-only register will cause unexpected results.
\n\n…
\n\nWhen strobing any register which responds to either a read or a write, (for example copjmp2) be sure \nto use a
\n\nMOVE.W
, notCLR.W
. TheCLR
instruction causes a read and a clear (two access) on a 68000,\nbut only a single access on 68020 processors. This will give different results on different processors.
The Color Computer isn't quite as finicky\n(although the 6809 inside it also does the “read, then write” thing with the CLR
instruction),\nbut there is still memory-mapped IO that is read-only, some that is write-only,\nand some that has different meanings when reading and writing.\nAnd while C has some semantic support with volatile
\n(to ensure reads and writes happen when stated)\nand const
\n(to ensure the read-only nature)\nit still lacks a “write-only” concept.\nAnd I've never used an assembler that had “write-only” semantics either.
I'm thinking something along these lines:
\n\n\n\t\torg\t$FF40\nDSK.CTRL\trmb/w\t1\t; write only\n\n\t\torg\t$FF48\nDSK.CMD\t\trmb/w\t1\t; write only\n\t\torg\t$FF48\nDSK.STATUS\trmb/r\t1\t; read only\n\nDSK.TRACK\trmb\t1\t; these can be read and written\nDSK.SECTOR\trmb\t1\nDSK.DATA\trmb\t1\n\n\n\n
Here, the RMB
directive just reserves a number of bytes, with a default access of “read-write.”\nThe /W
or /R
designates that label as being either “write-only” or “read-only.”\nAnd if you look closely,\nyou'll see that both DSK.CMD
and DSK.STATUS
are defined as the same address.\nIt's just that writing to that address will send a command to the drive controller,\nwhile reading from that address give the current status.\nThe only issue I have are hardware registers that can be programmed for input or output.\nThe MC6821 used in the Color Computer has such registers,\nand the issue I have is how to signify this change in state in a program—that at this point in the program,\nsuch-n-such address is “read-write” but afterwards, it's “write-only.”
I cross post links to my blog on LinkedIn mainly to be contrarian,\nor at least think I'm providing something different than all the business related stuff posted there.\nBut lately,\nI've seen notifications there like,\n“You're one of the few experts invited to add this collaborative article: …” and it's some article about AI,\nor Agile or the latest one,\n“Your team is falling behind on project deadlines. What web-based tools can help you catch up?”\n\n
Oh … nothing good can come from me answering these questions.
\n\n", "date_published" : "2024-02-01T06:02:36Z", "tags" : [ "LinkedIn","drinking the Flavor Aid","silver bullets","MBA brain damage" ] } ] }