Post by hydrophilic on Mar 2, 2015 7:03:29 GMT
Here is a new bug brought to my attention by Donno128: SCALE is broken with custom X/Y values -- well *some* values.
In case you are not familiar with SCALE, let me give you the background details...
So standard BASIC of the Plus/4 and C=128 have two "real" bitmap modes... often called "hi-res" and "multicolor" (or more briefly, HR and MC). Going off-topic a bit, there are two extra "software" modes that mix bitmap and text mode. I won't discuss them here to avoid confusion
So in hi-res mode, the screen is physically divided into 320(H) by 200(V) pixels... and in multicolor mode, the physical bitmap is 160(H) by 200(V) pixels. I think anyone familiar with TED / VIC-II graphics knows this.
Because these values are quite arbitrary (and mode-specific), somebody at CBM thought it would be a good idea to implement a SCALE command. This allows "logical" coordinates to be used with bitmap commands (instead of "physical" coordinates).
This idea is a good thing as it allows, for example, a generic program to be written with some logical SCALE factor that will work "acceptably" no matter which physical mode is used... "acceptable" means it would look approximately the same, but there may be some "minor" differences... (and "minor" means the program should work most of the time, but could cause trouble in marginal cases... especially with PAINT)
*ANYWAY*
If you look at the documentation for the C128 (either in the C128 System Guide that comes with the computer, or the "bible" known as C128 Programmer's Reference Guide) then you will find the following documentation....
SCALE [n, XMAX, YMAX]
where:
n = 0 or 1 (off or on [physical or logical])
XMAX = physical-X to 32767 (only if n=1... ignored if n=0)
YMAX = physical-Y to 32767 (only if n=1)
(P.S.: from memory the same thing is documented for Plus/4, although I have not verified this)
For both VIC-II and TED (both BASIC 3.5 and 7.0), the "physical-Y" is always 200, thus...
YMAX = 200 to 32767 (only if n=1)
However, for both VIC-II and TED, the "physical-X" will be either 160 or 320 depending on bitmap mode (for our purposes, GRAPHIC 1 or GRAPHIC 3). Thus...
XMAX = 320 to 32767 (if n=1 and "hi-res" mode)
or
XMAX = 160 to 32767 (if n=1 and "multicolor" mode)
Well I hope that makes sense to everybody, because things only get worse!
Donno128 recently reported to me that "the VIC screen scale command has been broken back to Plus/4 compatibility... It does not accept x and y arguments but reports a division by zero error"
Well I tried some "marginal" values and got errors in C128 (have not tested Plus/4). Edit: I got same error with Plus/4 using GRAPHIC 3,1: SCALE 1,200,200 /Edit
My investigation is not complete, but from both standard BASIC of Plus/4 and C128 (version 3.5 and 7.0, respectively) I did get an error... but for me the error was ILLEGAL QUANTITY ERROR.
So attached are 3 BASIC programs... the first and second (for Plus/4 and C128) attempt to use SCALE of 200x200 in multicolor mode... but they give ILLEGAL QUANTITY ERROR [in 20].
The third program (only tested on C128) , "works" at first (i.e., no error message) but according to the SCALE used, the BOX should be completely ON-SCREEN... however if you run it on your C128 (probably Plus/4 too) you see the first box drawn is NOT fully on-screen... it gets "cut-off" (on the right).
Thus, it seems the problem is BAD DOCUMENTATION!
Upon further investigation (the C128 ROMs), it seems the problem is ROM bug... you see each video mode ("hi-res" or "multicolor") should use a different "scale factor"... but the ROM uses a hard-coded value without any regard to the current screen mode:
;perform SCALE
. F6960 20 F4 87 JSR $87F4 ;Evaluate to unsigned byte in .X
. F6963 E0 02 CPX #$02 ;limit boolean
. F6965 90 03 BCC $696A ;less than ok
.... F696A 8E 6A 11 STX $116A ;scaleM; set on (1) or off (0)
. F696D 20 86 03 JSR $0386 ;chrGot
. F6970 D0 14 BNE $6986 ;no terminator, get SCALE values
.... F6986 20 C4 69 JSR $69C4 ;Skip comma & evaluate positive 16 bit number to FAC
. F6989 A9 D8 LDA #$D8 ;address of SCALE horizontal factor (lo)
. F698B A0 69 LDY #$69 ;(hi) ***** hard-coded value = NOT mode specific ******
. F698D 20 89 8A JSR $8A89 ;ROMupk: Copy float from address .YA to arg
. F6990 20 4C 8B JSR $8B4C ;FdivT: fac = arg / fac
. F6993 20 15 88 JSR $8815 ;FAC to unsigned integer in .AY and poker
. F6996 C9 00 CMP #$00 ;test hi byte
. F6998 D0 04 BNE $699E
. F699A C0 00 CPY #$00 ;test lo byte
. F699C F0 37 BEQ $69D5 ;Illegal Quantity Error
. F699E 48 PHA
. F699F 98 TYA
. F69A0 48 PHA
. F69A1 20 C4 69 JSR $69C4 ;Skip comma & evaluate positive 16 bit number to fac
. F69A4 A9 DD LDA #$DD ;address of SCALE vertical factor (lo)
. F69A6 A0 69 LDY #$69 ;(hi)
. F69A8 20 89 8A JSR $8A89 ;ROMupk: Copy float from address .YA to arg
. F69AB 20 4C 8B JSR $8B4C ;FdivT: fac = arg / fac
. F69AE 20 15 88 JSR $8815 ;fac to unsigned integer in .AY and poker
. F69B1 C9 00 CMP #$00 ;test hi byte
. F69B3 D0 04 BNE $69B9
. F69B5 C0 00 CPY #$00 ;test lo byte
. F69B7 F0 1C BEQ $69D5 ;Illegal Quantity Error
. F69B9 84 89 STY $89 ;scaleY(lo)
. F69BB 85 8A STA $8A ;scaleY(hi)
. F69BD 68 PLA
. F69BE 85 87 STA $87 ;scaleX(lo)
. F69C0 68 PLA
. F69C1 85 88 STA $88 ;scaleX(hi)
. F69C3 60 RTS
So the documentation is NOT true to the real ROM behavior... in particular...
. F6989 A9 D8 LDA #$D8 ;address of SCALE horizontal factor (lo)
. F698B A0 69 LDY #$69 ;(hi) ***** hard-coded value = NOT mode specific ******
. F698D 20 89 8A JSR $8A89 ;ROMupk: Copy float from address .YA to arg
It seems like BASIC should use a different SCALE factor (near the hex address $6989 on the C128) based on the current mode. Donno128 reported that SCALE works correctly with BASIC 7.80 when using 80-column screen (because my software actually tests the video mode), however for non-80 column (VIC) screen the original ROM routine is used (which does NOT test the mode).
And so there is a bug with 40 columns... blame the ROM or blame the documentation (but don't blame me )
I could patch my BASIC 7.80 to correct for this bug in the original ROMs... but of course that risks breaking compatibility with existing software. Considering SCALE is not very popular (from my limited survey of C128 software) this might be acceptable...
What do you folks think?
Tell us off-the-top-of-your-head, or if you are a real Commie, do some tests on your favorite machine and then report...
Edit
Oh yeah, here are the BASIC programs I used for testing... the one with "+4" in the name is for Plus/4 (shock ) and the other 2 are for C128.
+Edit 2
I noticed the forum software renamed "+4" in the first filename to simply "4"... I guess this is a Linux limitation on filenames?
/Edit 2
/Edit