Elsewhere on this site, I've seen various code examples for programming the VDC from BASIC using POKEs and PEEKs. This method of programming the VDC is incorrect and may cause all sorts of strange and hard-to-fix errors. Below is an edited statement that was originally found in the VDC technical documentation provided to early 128 developers:
Commodore's specifications for this chip state that when accessing the VDC, you should avoid machine language instructions that use the indirect addressing mode. That is, you should avoid using instructions like LDA ($CC),Y to read this register because the VDC apparently responds improperly to such instructions. This imposes no particular hardship on machine language programmers, but has highly unfortunate consequences for BASIC programmers. The 128's PEEK, POKE, and WAIT instructions are implemented using the Kernal INDFET, INDSTA, and INDCMP routines, all of which use indirect-Y addressing to read or store values. As a result, you should not use PEEK, POKE, or WAIT statements to read or change the contents of the VDC registers.
The correct way to control the VDC from BASIC is by using two screen editor ROM primitives located at $CDCC and $CDDA. The former, officially referred to as WRITEREG, writes to a selected register in the VDC. The other location, READREG, reads from a selected VDC register.
To use WRITEREG from BASIC, you would code:
BANK 15:SYS("CDCC"),D,R
where D is the byte to be written and R is the desired register number.
To use READREG from BASIC, you would code:
BANK 15:SYS("CDDA"),,R:RREG D
where R is the desired register number. The value in the register will be returned in D.
This quirk in the C-128's hardware was apparently discovered during the prototyping phase, but was never fixed. The story I was told by Fred Bowen was that everyone was rushing to complete a working machine in time for demonstration at the January 1985 Consumer Electronics Show. When this little gotcha was discovered, there wasn't enough time to do a new mask for the 8563, which had experienced all sorts of teething problems from the get go. So the problem has persisted to this day.
Please! Let's get it right for the noobies who are learning how to make their C-128s do what they want. Perpetuating the PEEK/POKE method simply complicates things for them.
Interesting, I had read about the indirect addressing mode but didnt realise peek/poke etc used it.
I cant get my head around the logic of it though. Itd be nice to understand why. I cant see why indirect addressing is a special case.
Just as an aside, I recently did a 64k upgrade and ran the old basic test - first time I ran it, it failed. I was just about to panic and reach for the soldering iron again when I ran it again and it worked. Possibly Id made a typo, but I guess there's also a chance that the write failed.
Quote from: BigDumbDinosaur on January 21, 2008, 09:18 AMThe 128's PEEK, POKE, and WAIT instructions are implemented using the Kernal INDFET, INDSTA, and INDCMP routines, all of which use indirect-Y addressing to read or store values. As a result, you should not use PEEK, POKE, or WAIT statements to read or change the contents of the VDC registers.
Well then, we'll just switch to 64 mode and do our PEEKs and POKEs from there. :P
Seriously, though, I'm all for Sticky-ing this thread.
Lance?EDIT: Ah, found my Sticky button.
Quote from: Michael Hart on January 21, 2008, 10:37 AM
Quote from: BigDumbDinosaur on January 21, 2008, 09:18 AMThe 128's PEEK, POKE, and WAIT instructions are implemented using the Kernal INDFET, INDSTA, and INDCMP routines, all of which use indirect-Y addressing to read or store values. As a result, you should not use PEEK, POKE, or WAIT statements to read or change the contents of the VDC registers.
Well then, we'll just switch to 64 mode and do our PEEKs and POKEs from there. :P
You'll experience the same problem, since PEEK and POKE in BASIC 2.0 is implemented with indirect addressing as well. A tiny M/L priimitive is all that's needed to drive the VDC on the 64 side:
stx $d600 ;set register to be accessed
wait bit $d600 ;wait until VDC is ready
bpl wait
lda $d601 ;read register
---or---
sta $d601 ;write register
rts
That's all there is to it and it works like a charm every time. You can stash that little subroutine almost anywhere (except in the $D000 range, of course). Do it right and it'll work right. Do it with PEEK and POKE and you'll go nuts with random errors.
Just to answer my own question, I googled a bit and it seems that STA($ZP),Y will fail sometimes because the cycle before it does the write, it does a read...... Depending on the timing (given that the CPU clock and VDC clock are asynchronous), Im guessing that it would mean that the read and write can sometimes occur in the same VDC clock (maybe), which would cause an issue.
Something like that anyway.
Quote from: StyleCHM on January 21, 2008, 11:31 AM
Just to answer my own question, I googled a bit and it seems that STA($ZP),Y will fail sometimes because the cycle before it does the write, it does a read...... Depending on the timing (given that the CPU clock and VDC clock are asynchronous), Im guessing that it would mean that the read and write can sometimes occur in the same VDC clock (maybe), which would cause an issue.
Something like that anyway.
I've never found or heard a satisfactory explanation for this problem, except that the evanesence of the VDC's registers may be to blame. I don't know that it is a clocking issue, since access to anything in the I/O block occurs on the 1 MHz clock, regardless of processor clock speed. However, the VDC does have its own video dot clock and therefore there may be internal issues involving timing between the I/O clock and the dot clock.
I got my first C-128 in September 1985 and by good fortune, was able to get my hands on technical information that wasn't generally available. I recall playing around with the POKE and PEEK techniques and simply not being able to get consistent results. Then I started digging into the docs and discovered the caveat about indirect loads and stores to the VDC. That prompted me to dig into the screen editor ROM, since I surmised that there must be a bullet-proof way of driving the VDC—the ROM routines seemed to work very well.
The first thing I wrote for the 128 was a clock-calendar program that would drive a date and time display on both screens from interrupts. It was an interesting exercise getting the 80 column side to work right, due to the need to avoid tripping over the screen editor ROM when it was updating the VDC. It took stack sniffing to watch for when something else was accessing the VDC—my program would skip the 80 column update if it saw anything on the stack that indicated the VDC was being driven by ROM.
I later developed a trickier version of the clock-calendar program that created a status line at the bottom of the screen on an extra row created by twiddling with the VDC. Again, stack sniffing kept my code from interfering with the editor ROM.
Quote from: BigDumbDinosaur on January 21, 2008, 11:02 AM
Quote from: Michael Hart on January 21, 2008, 10:37 AM
Well then, we'll just switch to 64 mode and do our PEEKs and POKEs from there. :P
You'll experience the same problem, since PEEK and POKE in BASIC 2.0 is implemented with indirect addressing as well. A tiny M/L priimitive is all that's needed to drive the VDC on the 64 side:
Sorry, I should've made it more clear I was joking about Commodore naming INDFET et al here, as if the indirect addressing is 128 mode specific, when in fact, as you point out, PEEK and POKE use indirect addressing in 64 mode as well. But nonetheless your ML is useful to have here, so thank you for adding it to the thread.
Quote from: StyleCHM on January 21, 2008, 10:25 AM
Interesting, I had read about the indirect addressing mode but didnt realise peek/poke etc used it.
I cant get my head around the logic of it though. Itd be nice to understand why. I cant see why indirect addressing is a special case.
I don't wonder why it sometimes fails, I wonder how it ever works.
http://home.datacomm.ch/fmeyer/c64/c128_story.html
Since I apparently have opened up a can of worms with this topic, I thought that maybe I should post a response that I placed elsewhere to the subject of figuring out how much video RAM is hooked up to the VDC.
Quote from: xlar54 on January 21, 2008, 03:16 PM
Since we're in the thread, can you help with a quick ML or BASIC routine one might call to determine 16k or 64k by using the correct access method?
Your wish is (somewhat) my command.
Rotting somewhere in this vast depository of refuse I call my shop are some assembly language listings of code I hammered into the 128 back in the day. I'm reasonably certain that an M/L routine I wrote for positively detecting the amount of video RAM hooked up to the VDC is in that compost pile. Once I find it, I'll get it into a format that can be somehow made available to anyone who has a MOS Technology-compliant assembler.
My recollection is that late in 1987, I was on the horn with Fred Bowen on another matter and the subject of determining how much video RAM was installed came up. Fred described to over the phone how to conduct such a test—telling me which video RAM locations to twiddle, etc. I jotted some notes and was going to start programming when Fred said he could FAX me a copy of a BASIC program he had written to do the testing, but was not always working as it should. Turns out the trouble was being caused by some
PEEKing and
POKEing he was doing to the VDC, which as everyone should know, doesn't work all the time.
Since I've never really liked BASIC, I said, "Screw that!" and using Fred's program as a guide (why reinvent the wheel) cobbled together a short M/L routine to do the testing. It worked fine on both of the flat 128s I had at the time, as well as my then newly-acquired 128D.
Since I'll be out of commission starting on Friday, I may not be able to get the source code up here for a while. First I have to find it, though. Otherwise, I will rewrite it from scratch, since for reasons that totally baffle me, I think I recall exactly how to do it. If I do rewrite it, I'll need some volunteers to test the result, since I don't have any real 128 hardware anymore and, unlike the current resident of the Vatican, I don't claim to be infallible.
BDD, for historical interest, this is what Fred was posting to Usenet years ago and may be similar or the same as what he sent you. Odd thing about it is that he uses calls to the screen editor most of the time, yet relies on PEEKs and POKEs for dealing with register 28. That inspired me to run a little "stress test" on my flat 128, where over 10000 operations each I found that reading or writing register 28 the wrong way usually succeeds, 18 and 19 often work, and 31 is completely hit or miss. PEEKing and POKEing the VDC could be fun stuff if one were a gambling man. :)
Original:
1 rem fred's nifty program to determine size of 8563 dram
5 w=dec("cdcc"):r=dec("cdda")
10 bank15: ad=dec("d600"): da=ad+1 :rem setup ml
20 pokead,28: s=peek(da): pokeda,63 :rem select 64k
30 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,85,31 :rem write $55
40 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc1 :rem read here
50 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc2 :rem and here
60 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,170,31 :rem write $aa
70 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc3 :rem read here
80 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc4 :rem and here
90 pokead,28: pokeda,s:sysdec("ff62") :rem restore 16/64k
95 print chr$(14)chr$(147)
100 if c1=c2 and c3=c4 then print "16K": else print"64K" :rem did it echo?
110 end
Corrected to remove PEEKs and POKEs:
1 rem fred's nifty program to determine size of 8563 dram
5 w=dec("cdcc"):r=dec("cdda")
10 bank15: rem setup ml
20 sys r,,28: rreg s: sys w,63,28: rem select 64k
30 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,85,31 :rem write $55
40 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc1 :rem read here
50 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc2 :rem and here
60 i=16896: sysw,i/256,18:sysw,iand255,19:sysw,170,31 :rem write $aa
70 i=16896: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc3 :rem read here
80 i=17152: sysw,i/256,18:sysw,iand255,19:sysr,,31:rregc4 :rem and here
90 sys w,s,28:sysdec("ff62") :rem restore 16/64k
95 print chr$(14)chr$(147)
100 if c1=c2 and c3=c4 then print "16K": else print"64K" :rem did it echo?
110 end
Pretty straightforward to convert to M/L as it mainly works out to just a bunch of LDA #value, LDX #register, JSR writereg... LDX #register, JSR readreg, STA somewhere.
I found the much-wrinkled and yellowed, but otherwise readable, M/L source code listing for checking the amount of video RAM in a 128, but did not find the copy of the BASIC program that I got from Fred Bowen way back when. It appears, however, that what he posted in USENET is the same as what he had FAXed to me in 1987.
What follows is a cleaned-up version of the original source code. I've test-assembled it with my UNIX 6502 assembler (100 percent MOS Technology compliant, except it supports longer labels and symbols) and it should be good to try out. I haven't tested it on a real 128, since I don't have access to one. However, I see no reason why it shouldn't work. It assembles into the 128's cassette buffer at $0B00, but may be relocated as needed, as long as it is visible in RAM0 below $C000.
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* *
;* Test & Report Available Video RAM in C-128 *
;* *
;* This program positively determines the amount of video RAM connected to the *
;* 8563/8568 video display controller in the C-128. It is a machine language *
;* implementation of a BASIC 7.0 program written by CBM kernal developer Fred *
;* Bowen in late 1987. *
;* *
;* Copyright (c)1987 by BCS Technology Limited. Redistribution is permitted *
;* subject to retention of copyright notice & attribution. Any redistribution *
;* must be at no charge to the end user. *
;* *
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;* *
;* BASIC syntax for running this test: *
;* *
;* BANK 15 : SYS DEC("0B00") : RREG VS *
;* PRINT "This 128 has";VS;"K video RAM." *
;* *
;* VS will equal 16 for a C-128 with 16K of VRAM or 64 for a machine with *
;* with 64K of VRAM. *
;* *
;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
;
;* * * * * * * * * * *
;* *
;* REVISION HISTORY *
;* *
;* * * * * * * * * * *
;
;Ver Rev Date Revision
;================================================================================
;1.0 12/09/1987 Original version.
;================================================================================
;
;
;* * * * * * * * * * * * *
;* *
;* <<< PROGRAM NOTES >>> *
;* *
;* * * * * * * * * * * * *
;
;Comment abbreviations are as follows:
;
; .A MPU accumulator
; .X MPU X index register
; .Y MPU Y index register
; CBM Commodore Business Machines
; DRAM dynamic random access memory
; KRAM character shape RAM
; LSB least significant byte
; MPU microprocessor
; MSB most significant byte
; VDC 8563/8568 video display controller
; VRAM VDC video RAM (16K or 64K)
;
;================================================================================
;
;main program declarations
;
_origin_ =$0b00 ;cassette buffer, relocate if desired
;
dlchr =$c027 ;initialize VDC character RAM
mmucr =$ff00 ;MMU config register
mmumask =%00001110 ;memory map mask
ramsmall =16 ;returned for 16K VRAM
ramlarge =64 ;returned for 64K VRAM
read80 =$cdd8 ;read from VRAM primitive
readreg =$cdda ;read from VDC register primitive
testadra =$4200 ;1st VRAM test address
testadrb =$4300 ;2nd VRAM test address
testpata =%01010101 ;test bit pattern #1
testpatb =%10101010 ;test bit pattern #2
testvrt =%00110000 ;DRAM type register setup value
write80 =$cdca ;write to VRAM primitive
writereg =$cdcc ;write to VDC register primitive
;
;================================================================================
;
;8563/8568 VDC internal registers
;
vramhi =18 ;VRAM address (MSB), autoincrementing
vramlo =19 ;VRAM address (LSB), autoincrementing
kramad =28 ;KRAM starting address & VRAM type...
;
; Bit Meaning
; ----------------------------------------
; 0-3 unused (mask off)
; 4 VRAM chip type: 0 = 4416 (flat 128)
; 1 = 4464 (128DCR)
; 5-7 start of KRAM
; ----------------------------------------
;
vramrw =31 ;VRAM read/write access
;
;================================================================================
;
;temporary storage -- can be moved from ZP if necessary
;
kramregv =$fa ;place to stash current KRAM value
rbitpata =$fb ;returned bit pattern from 1st test
rbitpatb =$fc ;returned bit pattern from 2nd test
rbitpatc =$fd ;returned bit pattern from 3rd test
rbitpatd =$fe ;returned bit pattern from 4th test
;
;================================================================================
;
*=_origin_
;
chkvdc lda #mmumask
sta mmucr ;select RAM0, I/O block & high ROM
;
; prepare VDC for testing...
;
ldx #kramad ;KRAM & VRAM type reg
jsr readreg ;get it...
and #%11110000 ;mask dead bits &...
sta kramregv ;stash it
lda #testvrt
jsr writereg ;tell VDC it has 64K VRAM
;
; The basis on which this test works is relatively simple. We've told
; the VDC that it has 4464 DRAM, which means it thinks that it has 64K
; of VRAM. If it really does, the column & row address enables associated
; with the selected test addresses will see real RAM. If only 16K of VRAM
; is present, the col/row enables will goof up & select the same hardware
; address despite the two disparate test addresses.
;
; So, what we're doing is writing some test patterns into RAM locations
; that could only exist if 64K of VRAM really was present. We then read
; the test VRAM locations & check for the presence of the test pattern.
; If the test pattern written into the lower of the test locations shows
; up in the higher location, then the machine has 16K of VRAM.
;
; To verify the results, 2 test patterns are used, with opposite bit
; patterns (01010101 & 10101010). This is done just in case one of the
; test locations in VRAM just happens to have one or the other test
; patterns.
;
; Note that checking the VRAM type in VDC register 28 is not reliable,
; since a program bug could change that value.
;
lda #testpata ;1st test pattern
ldx #<testadra ;1st VRAM test address LSB &...
ldy #>testadra ;MSB
jsr putram ;write test pattern
ldx #<testadra ;1st VRAM test address LSB &...
ldy #>testadra ;MSB
jsr getram ;read back test pattern &...
sta rbitpata ;store it for later
ldx #<testadrb ;2nd VRAM test address LSB &...
ldy #>testadrb ;MSB
jsr getram ;read &...
sta rbitpatb ;store it as well
;
; 1st test completed & results saved
;
lda #testpatb ;2nd test pattern
ldx #<testadra ;1st VRAM test address LSB &...
ldy #>testadra ;MSB
jsr putram ;write test pattern
ldx #<testadra ;1st VRAM test address LSB &...
ldy #>testadra ;MSB
jsr getram ;read back test pattern &...
sta rbitpatc ;store it for later
ldx #<testadrb ;2nd VRAM test address LSB &...
ldy #>testadrb ;MSB
jsr getram ;read &...
sta rbitpatd ;store it as well
;
; 2nd test completed & results saved
;
lda kramregv ;old KRAM register value
ldx #kramad ;KRAM & VRAM type reg
jsr writereg ;restore to original config
jsr dlchr ;restore character patterns in VRAM
;
; here we compare the returned test patterns
;
lda rbitpata ;1st low address returned test value
cmp rbitpatb ;1st high address returned test value
beq chkvdc02 ;same, possibly 16K VRAM
;
chkvdc01 lda #ramlarge ;indicate 64K VRAM
rts
;
chkvdc02 lda rbitpatc ;low address returned test value
cmp rbitpatd ;high address returned test value
bne chkvdc01 ;not same, VDC definitely has 64K VRAM
;
lda #ramsmall ;indicate 16K VRAM
rts
;
;================================================================================
;
;read from VRAM
;
; .X = VRAM address LSB
; .Y = VRAM address MSB
; ---------------------
; .A = returned byte
;
; registers not preserved
;
getram jsr setadr ;set VRAM address &...
jmp read80 ;read from VRAM
;
;================================================================================
;
;write to VRAM
;
; .A = byte to write
; .X = VRAM address LSB
; .Y = VRAM address MSB
;
; registers not preserved
;
putram jsr setadr ;set VRAM address &...
jmp write80 ;write to VRAM
;
;================================================================================
;
;set up VRAM address
;
; .X = VRAM address LSB
; .Y = VRAM address MSB
;
; registers preserved
;
setadr pha ;preserve registers
txa
pha
tya ;VRAM address MSB
ldx #vramhi ;select VRAM address register MSB
jsr writereg ;set address MSB
pla ;VRAM address LSB
ldx #vramlo ;select VRAM address register LSB
jsr writereg ;set address LSB
tax ;restore
pla ;likewise
rts
;
;================================================================================
The above should assemble okay in any assembler that follows the MOS Technology 6502 recommended source syntax. Be warned that many of the current Windows-based emulators and assemblers are not 100 percent correct in that regard. You may have to tinker with number radices and/or language syntax (e.g. ROR A vs. ROR for accumulator rotation). Also, your assembler might choke on eight-character labels and symbol names.
Please advise me if you try it out as to the results. Incidentally, testing this program in VICE or another 128 emulator will be a waste of time. At best, all you will know for sure is that the program doesn't do anything that is terminally stupid.
Thank you for posting your code. I've no doubt it will work just fine on a real machine, and I'm just as certain it will fail on VICE. VICE doesn't implement its VDC addressing correctly, so 16K & 64K will both be identified as 64K with this sort of test. Most programs aren't adversely affected, however, since VICE doesn't care one lick if you treat a 16K machine as a 64K one. Once that bit in register 28 is set, it will happily act like a 64K machine even if the emulator setting is otherwise. Perhaps the only code ever bitten by this is a weird little infinite scrolling routine I wrote that relies on correct behavior.
The VICE team was made aware of the issue a couple months ago and received a patch for it, so I trust (hope?) things will be fixed in a future version.
As a reference to my previously posted source code for checking video RAM, here is the assembly listing output from my UNIX 6502 assembler. I couldn't include it in the other post because of a character limit per post.
0001 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
0002 ;* *
0003 ;* Test & Report Available Video RAM in C-128 *
0004 ;* *
0005 ;* This program positively determines the amount of video RAM connected to the *
0006 ;* 8563/8568 video display controller in the C-128. It is a machine language *
0007 ;* implementation of a BASIC 7.0 program written by CBM kernal developer Fred *
0008 ;* Bowen in late 1987. *
0009 ;* *
0010 ;* Copyright (c)1987 by BCS Technology Limited. Redistribution is permitted *
0011 ;* subject to retention of copyright notice & attribution. Any redistribution *
0012 ;* must be at no charge to the end user. *
0013 ;* *
0014 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
0015 ;
0016 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
0017 ;* *
0018 ;* BASIC syntax for running this test: *
0019 ;* *
0020 ;* BANK 15 : SYS DEC("0B00") : RREG VS *
0021 ;* PRINT "This 128 has";VS;"K video RAM." *
0022 ;* *
0023 ;* VS will equal 16 for a C-128 with 16K of VRAM or 64 for a machine with *
0024 ;* with 64K of VRAM. *
0025 ;* *
0026 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
0027 ;
0028 ;* * * * * * * * * * *
0029 ;* *
0030 ;* REVISION HISTORY *
0031 ;* *
0032 ;* * * * * * * * * * *
0033 ;
0034 ;Ver Rev Date Revision
0035 ;================================================================================
0036 ;1.0 12/09/1987 Original version.
0037 ;================================================================================
0038 ;
0039 ;
0040 ;* * * * * * * * * * * * *
0041 ;* *
0042 ;* <<< PROGRAM NOTES >>> *
0043 ;* *
0044 ;* * * * * * * * * * * * *
0045 ;
0046 ;Comment abbreviations are as follows:
0047 ;
0048 ; .A MPU accumulator
0049 ; .X MPU X index register
0050 ; .Y MPU Y index register
0051 ; CBM Commodore Business Machines
0052 ; DRAM dynamic random access memory
0053 ; KRAM character shape RAM
0054 ; LSB least significant byte
0055 ; MPU microprocessor
0056 ; MSB most significant byte
0057 ; VDC 8563/8568 video display controller
0058 ; VRAM VDC video RAM (16K or 64K)
0059 ;
0060 ;================================================================================
0061 ;
0062 ;main program declarations
0063 ;
0064 0B00 _origin_ =$0b00 ;cassette buffer, relocate if desired
0065 ;
0066 C027 dlchr =$c027 ;initialize VDC character RAM
0067 FF00 mmucr =$ff00 ;MMU config register
0068 000E mmumask =%00001110 ;memory map mask
0069 0010 ramsmall =16 ;returned for 16K VRAM
0070 0040 ramlarge =64 ;returned for 64K VRAM
0071 CDD8 read80 =$cdd8 ;read from VRAM primitive
0072 CDDA readreg =$cdda ;read from VDC register primitive
0073 4200 testadra =$4200 ;1st VRAM test address
0074 4300 testadrb =$4300 ;2nd VRAM test address
0075 0055 testpata =%01010101 ;test bit pattern #1
0076 00AA testpatb =%10101010 ;test bit pattern #2
0077 0030 testvrt =%00110000 ;DRAM type register setup value
0078 CDCA write80 =$cdca ;write to VRAM primitive
0079 CDCC writereg =$cdcc ;write to VDC register primitive
0080 ;
0081 ;================================================================================
0082 ;
0083 ;8563/8568 VDC internal registers
0084 ;
0085 0012 vramhi =18 ;VRAM address (MSB), autoincrementing
0086 0013 vramlo =19 ;VRAM address (LSB), autoincrementing
0087 001C kramad =28 ;KRAM starting address & VRAM type...
0088 ;
0089 ; Bit Meaning
0090 ; ----------------------------------------
0091 ; 0-3 unused (mask off)
0092 ; 4 VRAM chip type: 0 = 4416 (flat 128)
0093 ; 1 = 4464 (128DCR)
0094 ; 5-7 start of KRAM
0095 ; ----------------------------------------
0096 ;
0097 001F vramrw =31 ;VRAM read/write access
0098 ;
0099 ;================================================================================
0100 ;
0101 ;temporary storage -- can be moved from ZP if necessary
0102 ;
0103 00FA kramregv =$fa ;place to stash current KRAM value
0104 00FB rbitpata =$fb ;returned bit pattern from 1st test
0105 00FC rbitpatb =$fc ;returned bit pattern from 2nd test
0106 00FD rbitpatc =$fd ;returned bit pattern from 3rd test
0107 00FE rbitpatd =$fe ;returned bit pattern from 4th test
0108 ;
0109 ;================================================================================
0110 ;
0111 0B00 *=_origin_
0112 ;
0113 0B00 A9 0E chkvdc lda #mmumask
0114 0B02 8D 00 FF sta mmucr ;select RAM0, I/O block & high ROM
0115 ;
0116 ; prepare VDC for testing...
0117 ;
0118 0B05 A2 1C ldx #kramad ;KRAM & VRAM type reg
0119 0B07 20 DA CD jsr readreg ;get it...
0120 0B0A 29 F0 and #%11110000 ;mask dead bits &...
0121 0B0C 85 FA sta kramregv ;stash it
0122 0B0E A9 30 lda #testvrt
0123 0B10 20 CC CD jsr writereg ;tell VDC it has 64K VRAM
0124 ;
0125 ; The basis on which this test works is relatively simple. We've told
0126 ; the VDC that it has 4464 DRAM, which means it thinks that it has 64K
0127 ; of VRAM. If it really does, the column & row address enables associated
0128 ; with the selected test addresses will see real RAM. If only 16K of VRAM
0129 ; is present, the col/row enables will goof up & select the same hardware
0130 ; address despite the two disparate test addresses.
0131 ;
0132 ; So, what we're doing is writing some test patterns into RAM locations
0133 ; that could only exist if 64K of VRAM really was present. We then read
0134 ; the test VRAM locations & check for the presence of the test pattern.
0135 ; If the test pattern written into the lower of the test locations shows
0136 ; up in the higher location, then the machine has 16K of VRAM.
0137 ;
0138 ; To verify the results, 2 test patterns are used, with opposite bit
0139 ; patterns (01010101 & 10101010). This is done just in case one of the
0140 ; test locations in VRAM just happens to have one or the other test
0141 ; patterns.
0142 ;
0143 ; Note that checking the VRAM type in VDC register 28 is not reliable,
0144 ; since a program bug could change that value.
0145 ;
0146 0B13 A9 55 lda #testpata ;1st test pattern
0147 0B15 A2 00 ldx #<testadra ;1st VRAM test address LSB &...
0148 0B17 A0 42 ldy #>testadra ;MSB
0149 0B19 20 6B 0B jsr putram ;write test pattern
0150 0B1C A2 00 ldx #<testadra ;1st VRAM test address LSB &...
0151 0B1E A0 42 ldy #>testadra ;MSB
0152 0B20 20 65 0B jsr getram ;read back test pattern &...
0153 0B23 85 FB sta rbitpata ;store it for later
0154 0B25 A2 00 ldx #<testadrb ;2nd VRAM test address LSB &...
0155 0B27 A0 43 ldy #>testadrb ;MSB
0156 0B29 20 65 0B jsr getram ;read &...
0157 0B2C 85 FC sta rbitpatb ;store it as well
0158 ;
0159 ; 1st test completed & results saved
0160 ;
0161 0B2E A9 AA lda #testpatb ;2nd test pattern
0162 0B30 A2 00 ldx #<testadra ;1st VRAM test address LSB &...
0163 0B32 A0 42 ldy #>testadra ;MSB
0164 0B34 20 6B 0B jsr putram ;write test pattern
0165 0B37 A2 00 ldx #<testadra ;1st VRAM test address LSB &...
0166 0B39 A0 42 ldy #>testadra ;MSB
0167 0B3B 20 65 0B jsr getram ;read back test pattern &...
0168 0B3E 85 FD sta rbitpatc ;store it for later
0169 0B40 A2 00 ldx #<testadrb ;2nd VRAM test address LSB &...
0170 0B42 A0 43 ldy #>testadrb ;MSB
0171 0B44 20 65 0B jsr getram ;read &...
0172 0B47 85 FE sta rbitpatd ;store it as well
0173 ;
0174 ; 2nd test completed & results saved
0175 ;
0176 0B49 A5 FA lda kramregv ;old KRAM register value
0177 0B4B A2 1C ldx #kramad ;KRAM & VRAM type reg
0178 0B4D 20 CC CD jsr writereg ;restore to original config
0179 0B50 20 27 C0 jsr dlchr ;restore character patterns in VRAM
0180 ;
0181 ; here we compare the returned test patterns
0182 ;
0183 0B53 A5 FB lda rbitpata ;1st low address returned test value
0184 0B55 C5 FC cmp rbitpatb ;1st high address returned test value
0185 0B57 F0 03 beq chkvdc02 ;same, possibly 16K VRAM
0186 ;
0187 0B59 A9 40 chkvdc01 lda #ramlarge ;indicate 64K VRAM
0188 0B5B 60 rts
0189 ;
0190 0B5C A5 FD chkvdc02 lda rbitpatc ;low address returned test value
0191 0B5E C5 FE cmp rbitpatd ;high address returned test value
0192 0B60 D0 F7 bne chkvdc01 ;not same, VDC definitely has 64K VRAM
0193 ;
0194 0B62 A9 10 lda #ramsmall ;indicate 16K VRAM
0195 0B64 60 rts
0196 ;
0197 ;================================================================================
0198 ;
0199 ;read from VRAM
0200 ;
0201 ; .X = VRAM address LSB
0202 ; .Y = VRAM address MSB
0203 ; ---------------------
0204 ; .A = returned byte
0205 ;
0206 ; registers not preserved
0207 ;
0208 0B65 20 71 0B getram jsr setadr ;set VRAM address &...
0209 0B68 4C D8 CD jmp read80 ;read from VRAM
0210 ;
0211 ;================================================================================
0212 ;
0213 ;write to VRAM
0214 ;
0215 ; .A = byte to write
0216 ; .X = VRAM address LSB
0217 ; .Y = VRAM address MSB
0218 ;
0219 ; registers not preserved
0220 ;
0221 0B6B 20 71 0B putram jsr setadr ;set VRAM address &...
0222 0B6E 4C CA CD jmp write80 ;write to VRAM
0223 ;
0224 ;================================================================================
0225 ;
0226 ;set up VRAM address
0227 ;
0228 ; .X = VRAM address LSB
0229 ; .Y = VRAM address MSB
0230 ;
0231 ; registers preserved
0232 ;
0233 0B71 48 setadr pha ;preserve registers
0234 0B72 8A txa
0235 0B73 48 pha
0236 0B74 98 tya ;VRAM address MSB
0237 0B75 A2 12 ldx #vramhi ;select VRAM address register MSB
0238 0B77 20 CC CD jsr writereg ;set address MSB
0239 0B7A 68 pla ;VRAM address LSB
0240 0B7B A2 13 ldx #vramlo ;select VRAM address register LSB
0241 0B7D 20 CC CD jsr writereg ;set address LSB
0242 0B80 AA tax ;restore
0243 0B81 68 pla ;likewise
0244 0B82 60 rts
0245 ;
0246 ;================================================================================
As I said, VICE is not the proper place to test this program. It apparently does not account for real hardware subtleties. Please only report results from testing on the genuine article.
Quote from: BigDumbDinosaur on January 23, 2008, 06:04 AM
As I said, VICE is not the proper place to test this program.
Indeed. I just wanted people to be aware that testing in VICE would be not only inconclusive, but utterly useless (at least with 1.22 or earlier). Maybe 1.23 will be fixed for this.
Here's an assembled version of your code: vdcramtest (http://2mhz.net/vdcramtest). (moderator's note: this link is dead)
BLOAD "vdcramtest"
BANK 15 : SYS DEC("0B00") : RREG VS
PRINT "This 128 has";VS;"K video RAM."
Quote from: Michael Hart on January 23, 2008, 08:05 AM
Quote from: BigDumbDinosaur on January 23, 2008, 06:04 AM
As I said, VICE is not the proper place to test this program.
Indeed. I just wanted people to be aware that testing in VICE would be not only inconclusive, but utterly useless (at least with 1.22 or earlier). Maybe 1.23 will be fixed for this.
Here's an assembled version of your code: vdcramtest (http://2mhz.net/vdcramtest).
BLOAD "vdcramtest"
BANK 15 : SYS DEC("0B00") : RREG VS
PRINT "This 128 has";VS;"K video RAM."
Have you tried it on a real 128?
BTW, if you see a lot of my posts with edit dates in them, that's because the drugs I'm on right now to prepare me for surgery are messing with manual dexterity and vision, and I'm having to repeatedly fix typos that are somehow escaping my attention.
Also, there's some kind of a contrast problem with these pages. The text isn't dark enough relative to the background and I can't do anything to improve the situation. It particularly causes me problems with narrow letters, such as lower case "L" and "i". I usually avoid contrast issues when pounding in code by using the traditional "green screen" display in the editor.
Actually, I prefer to blame the interrupt handler that scans the keyboard for messing up my typing, but that excuse probably won't fly. ;-)
Nope, I haven't tried it yet. Even though it's short, I wasn't in the mood to type it in on the real deal as I'm having a heck of a time readjusting to the keyboard after all these years. PCs with huge Backspace keys have rendered my pinky too lazy to stretch all the way to the corner, so on the 128 I drive myself crazy hitting CLR/HOME instead of INST/DEL when trying to fix typos. Maybe someone here wouldn't mind downloading the executable and transferring it over to their machine. If not, I'll type it in later and post again after I've tried it out.
I can relate with having typing issues here, though in my case I think it's due to being constantly sleepy. My asthma medicine really screws with my sleep, but without it I can barely breathe well enough to function. Changing to different medication was pretty disastrous, so I guess I'll take the insomnia and just keep editing my messages to fix typos and wring more sense out of my sentences.
Regarding contrast, have you tried any of the other themes? Lance added a (mostly) black and white theme, and I wonder if that would be easier on your eyes?
Quote from: Michael Hart on January 23, 2008, 12:34 PM
Nope, I haven't tried it yet. Even though it's short, I wasn't in the mood to type it in on the real deal as I'm having a heck of a time readjusting to the keyboard after all these years. PCs with huge Backspace keys have rendered my pinky too lazy to stretch all the way to the corner, so on the 128 I drive myself crazy hitting CLR/HOME instead of INST/DEL when trying to fix typos. Maybe someone here wouldn't mind downloading the executable and transferring it over to their machine. If not, I'll type it in later and post again after I've tried it out.
I know what you mean about the Ins/Del key being on the small side. It has been over 13 years since I touched a 128 keyboard, so I imagine if I ever do again, I'll probably being tripping all over myself.
Quote from: Michael Hart on January 23, 2008, 12:34 PM
I can relate with having typing issues here, though in my case I think it's due to being constantly sleepy. My asthma medicine really screws with my sleep, but without it I can barely breathe well enough to function. Changing to different medication was pretty disastrous, so I guess I'll take the insomnia and just keep editing my messages to fix typos and wring more sense out of my sentences.
Asthma is one of those things where nothing ever works exactly right. As long as the oxygen going in exceeds the demand, you'll be okay, if a little short of breath. I had asthma difficulties as a child, and back then, the fast inhalers and such didn't exist. We had to use a glass nebulizer to get the bronchodilator into a form that could be inhaled. Fortunately, the asthma subsided as I got into my teen years and ceased to be a problem. It was later discovered that my mother's incessant smoking was mostly to blame.
Quote from: Michael Hart on January 23, 2008, 12:34 PM
Regarding contrast, have you tried any of the other themes? Lance added a (mostly) black and white theme, and I wonder if that would be easier on your eyes?
That's the theme I'm using. It's the least difficult of the bunch. It could be that the font being used in the edit window is to blame. There doesn't seem to be a way to change, though. The contrast is bad.
Quote from: BigDumbDinosaur on January 23, 2008, 03:10 PM
That's the theme I'm using. It's the least difficult of the bunch. It could be that the font being used in the edit window is to blame. There doesn't seem to be a way to change, though. The contrast is bad.
Hmm, which browser do you use? Sometimes when I find a site's presentation disagreeable, I override the stylesheet with one I've customized. I'm going to need to do that here since I can hardly read the text in [ code ] blocks.
Quote from: Michael Hart on January 23, 2008, 03:38 PM
Quote from: BigDumbDinosaur on January 23, 2008, 03:10 PM
That's the theme I'm using. It's the least difficult of the bunch. It could be that the font being used in the edit window is to blame. There doesn't seem to be a way to change, though. The contrast is bad.
Hmm, which browser do you use? Sometimes when I find a site's presentation disagreeable, I override the stylesheet with one I've customized. I'm going to need to do that here since I can hardly read the text in [ code ] blocks.
I'm using SeaMonkey. This is the only site I regularly visit with this problem. I can live with it for now.
Update: Went ahead and carefully typed your code in on my flat 128 with unexpanded VDC. As expected, it correctly reported 16K of video RAM.
Quote from: Michael Hart on January 23, 2008, 04:20 PM
Update: Went ahead and carefully typed your code in on my flat 128 with unexpanded VDC. As expected, it correctly reported 16K of video RAM.
That's good news. When the program ran, did you notice any disturbance to the display?
Well, I can't actually view 80 column mode reliably (my hacked together cable stinks), so I can't comment on visual disturbances, but on giving the routine and the original it's based on some further thought, I think there could be an unintended consequence on 16K setups like mine.
In Hydrophilic's earlier investigations of VDC addressing, if I understood him correctly, he determined that when 64K mode is set on a VDC with only 16K installed, the following happens to addresses: the high byte is divided by two, and the high nibble is ignored. For example, if you write a value to $1000 or $1100 (or $9000 or $9100), then switch back to 16K mode, you'll find that value at $800. So, it should follow that when writing to $4200 or $4300, the "real" address that is being accessed is $2100. If that is indeed the case, that would usually put us right into character definition territory, and should overwrite the first byte of an upper case 'P'.
But since you didn't mention any such consequence, and I don't know of anyone complaining in all these years that Fred's routine screwed up someone's 'P', I'm going to assume that I probably misunderstood Hydrophilic and went wrong in my analysis somewhere. If I'd remembered to save your program to disk before turning off my 128 (d'oh!), I'd be able to give you a definite answer now, but I'll have to get back to you later after I type it in again and check if KRAM is indeed being written to.
Quote from: Michael Hart on January 24, 2008, 04:56 AM
Well, I can't actually view 80 column mode reliably (my hacked together cable stinks), so I can't comment on visual disturbances, but on giving the routine and the original it's based on some further thought, I think there could be an unintended consequence on 16K setups like mine.
In Hydrophilic's earlier investigations of VDC addressing, if I understood him correctly, he determined that when 64K mode is set on a VDC with only 16K installed, the following happens to addresses: the high byte is divided by two, and the high nibble is ignored. For example, if you write a value to $1000 or $1100 (or $9000 or $9100), then switch back to 16K mode, you'll find that value at $800. So, it should follow that when writing to $4200 or $4300, the "real" address that is being accessed is $2100. If that is indeed the case, that would usually put us right into character definition territory, and should overwrite the first byte of an upper case 'P'.
But since you didn't mention any such consequence, and I don't know of anyone complaining in all these years that Fred's routine screwed up someone's 'P', I'm going to assume that I probably misunderstood Hydrophilic and went wrong in my analysis somewhere. If I'd remembered to save your program to disk before turning off my 128 (d'oh!), I'd be able to give you a definite answer now, but I'll have to get back to you later after I type it in again and check if KRAM is indeed being written to.
You are correct in that a write to the two test locations in VRAM on a 16K machine will land smack-dab in the middle of character defintion RAM, causing possible visible screen chaos. If you look at the source code you will see I have a call to the screen editor's
DLCHR (
$C027) subroutine immediately after testing has been done.
DLCHR regenerates the VDC's default character definitions, thus undoing the effects of the test.
BTW, I'm hoping that others will read the source code and thus better understand why Fred Bowen's seemingly-convoluted BASIC program is as it is. When it comes to otherwise uninitialized DRAM, you cannot assume that any given memory cell contains a known bit-pattern. That is why the double test with the
01010101 (
$55) and
10101010 (
$AA) bit patterns is performed.
Ah, I forgot about the call at the end. Sometimes I hyperfocus on one detail then miss the rest. It's amazing I've never gotten run over in a crosswalk for neglecting to look all ways.
Although it would add a little bit of code, why not stash the original value and restore it? If it's meaningless uninitialized DRAM, no harm done, and if it's meaningful, great, it's much faster than reloading the whole character set. More importantly, the call to DLCHR assumes that the user hasn't loaded a custom character set into VDC RAM prior to running the detection. If they have, we end up trashing it. While it may not affect many people, for those it does that's a pretty nasty side effect from something that's just supposed to report how much RAM is installed. I'm not blaming you at all -- Fred's original does exactly the same thing -- but I really don't think DLCHR is a reasonable shortcut instead of doing right by the end user.
Quote from: Michael Hart on January 24, 2008, 08:03 AM
Ah, I forgot about the call at the end. Sometimes I hyperfocus on one detail then miss the rest.
Although it would add a little bit of code, why not stash the original value and restore it? If it's meaningless uninitialized DRAM, no harm done, and if it's meaningful, great, it's much faster than reloading the whole character set. More importantly, the call to DLCHR assumes that the user hasn't loaded a custom character set into VDC RAM prior to running the detection. If they have, we end up trashing it. While it may not affect many people, for those it does that's a pretty nasty side effect from something that's just supposed to report how much RAM is installed. I'm not blaming you at all -- Fred's original does exactly the same thing -- but I really don't think DLCHR is a reasonable shortcut instead of doing right by the end user.
Well, you're assuming that the test write will actually hit the location we think it's going to hit on a 16K machine. 'Tis better to err on the side of caution and reload the defs. As for a user adding to or replacing the defs, wouldn't it be logical to first run the VRAM size test before doing anything that might change VRAM? Otherwise, it would be like a program assuming that X amount of memory is there and then try to use it.
Quote from: BigDumbDinosaur on January 24, 2008, 08:09 AM
Well, you're assuming that the test write will actually hit the location we think it's going to hit on a 16K machine.
I'm not assuming. I've now tested it, and it does. And even if it didn't, say it landed in unpredictable places on different 16K setups, it still makes a ton more sense to save and restore one or two locations than to replace an entire 8K. There's absolutely no reason this test needs to take close to a full second to complete. It wouldn't be unreasonable if the delay were necessary, but here it definitely isn't.
QuoteAs for a user adding to or replacing the defs, wouldn't it be logical to first run the VRAM size test before doing anything that might change VRAM?
You're assuming that this routine is only going to be used standalone by someone who doesn't know how much RAM is on their system or wants to test whether an upgrade worked. The routine could easily be incorporated into another program, say some sort of pop-up utility, where the end user may have no idea a RAM detection routine will be run or what effect it may have.
Quote'Tis better to err on the side of caution
I agree.
Quote...and reload the defs.
Apparently we have a different definition of being cautious.
EDIT: Anyway, this obviously comes down to a philosophical difference, so I'll drop it. You or others are welcome to discuss the issues, though.
Quote from: StyleCHMInteresting, I had read about the indirect addressing mode but didnt realise peek/poke etc used it.
I cant get my head around the logic of it though. Itd be nice to understand why. I cant see why indirect addressing is a special case.
I believe it's because the indirect addressing modes do 2 memory accesses sometimes. This is due to page boundary crossing. Specifically, when writing, the CPU will read the possibly wrong address (before page correction) and then do the actual write to the correct address (after page correction). Note this always happens on a write operation even if no page-boundary is crossed. A similar thing can occur during a read, but only if a page-boundary is crossed.
Also note the same addressing problem occurs with normal indexing modes for example LDA $D600,X or STA $D600,Y.
EditThis double-access can (likely will) cause problems with register 31 of the VDC because the memory-pointer auto-advances whenever a read or write operation is performed on $d601. Since a write via STA(zp),Y will perform 2 memory operations, this is bound to cause trouble! Why it would affect other VDC registers is beyond me...
/EditAnother problem with using BASIC PEEKs and POKEs, especially with register 31, is that you need to check $d600 to be sure the VDC is ready and then immediately send the data to $d601. If you wait several cycles (like during the parsing of a BASIC program), the write to $d601 can occur when the VDC has become busy again.
I must agree that using the editor ROM routines to read/write the VDC are the most reliable way to use the VDC from BASIC. Especially when accessing VDC memory via register 31. From a practical point of view, other VDC registers can be accessed with BASIC PEEKs and POKEs most of the time. So the question becomes, is 'most of the time' good enough for you?
Quote from: Michael Hart on January 24, 2008, 08:42 AM
Quote from: BigDumbDinosaur on January 24, 2008, 08:09 AM
Well, you're assuming that the test write will actually hit the location we think it's going to hit on a 16K machine.
I'm not assuming. I've now tested it, and it does. And even if it didn't, say it landed in unpredictable places on different 16K setups, it still makes a ton more sense to save and restore one or two locations than to replace an entire 8K. There's absolutely no reason this test needs to take close to a full second to complete. It wouldn't be unreasonable if the delay were necessary, but here it definitely isn't.
Okay, let's stop this right now. I'm going to get into your face a bit about this topic, because you are exhibiting an aspect of Commodore computer programming behavior that has annoyed me (and some of my former collaborators) for some 25 years. Please don't take offense, since what I'm going to say is borne out of literally decades of writing software at the machine level.
Very few amateur Commodore programmers have any of what I call "code discipline," which is the technique of writing structured programs in ways that are acceptable to professionals. This is okay if you're writing programs for your personal use and don't intend to share them. It's not so good if many others must also use the program. It's
totally unacceptable when the programmer makes unwarranted assumptions about undocumented hardware behavior. The latter is exactly what you are doing.
I don't know your computer background, but I'll tell you mine. I started out in 1970 pounding machine code into post office computers via a Tele-Type machine. In terms of 6502 M/L, I'd be willing to wager that I have pumped at least a quarter million lines of code into various 6502 powered devices (including Commodore computers) in the last 30 years, a lot of it working directly at the hardware level. One of my projects involved the Xetec Lt. Kernal hard drive subsystem, for which I scratch-wrote an ISAM database engine, and a set of applications to go with it. That one project had nearly 100,000 lines of M/L, much of it working at the raw disk level. Other parts of it included custom code to drive a non-standard 80 column display, which is where my understanding of the 8563/8568 was derived (it was also where the VRAM test was put to use). With that much M/L under my belt, I've developed a very deep level of hardware knowledge, and I believe I'm more than qualified to rebut what you are thinking.
During my days developing hardware drivers, I quickly learned several hard truths about working at the bare metal:
1) Never assume, unless stated otherwise by the manufacturer, that a hardware register will reset to a predictable state.
2) Never assume that hardware device will behave and/or respond in any way other than stated by the manufacturer.
3) Never assume that access to a dead area of the system map will produce identical results on different, but otherwise identical machines.
You are ignoring at least one of the above truths, number 3, in this case. You are assuming that a write access to a potentially non-existent memory location will behave the same way in every case and on every machine.
That assumption IS WRONG! There have been numerous times where I've seen totally unpredictable results when trying to write to non-existent physical RAM. This is the reason all computer systems conduct some sort of RAM detection/sizing test before announcing X number of KB or MB exist. The C-64 and 128 both do this at startup (see
RAMTAS in the kernal), and for very good reason: uninitialized DRAM is totally unpredictable in behavior.
There's absolutely nothing in the 8563/8568 technical specifications that even discusses how the device behaves when a memory access is attempted to a non-existent location. Therefore, why on earth would you even start to assume that it would be safe to read out what you think might be the actual location that would be affected by the RAM sizing test, when it is clear in reading the VDC tech docs that there's NO PREDICTABILITY in such an operation?
Quote from: Michael Hart on January 24, 2008, 08:42 AM
Quote from: BigDumbDinosaur on January 24, 2008, 08:09 AM
As for a user adding to or replacing the defs, wouldn't it be logical to first run the VRAM size test before doing anything that might change VRAM?
You're assuming that this routine is only going to be used standalone by someone who doesn't know how much RAM is on their system or wants to test whether an upgrade worked. The routine could easily be incorporated into another program, say some sort of pop-up utility, where the end user may have no idea a RAM detection routine will be run or what effect it may have.
No, I'm not assuming that the routine will be used standalone, but you seem to keep forgetting that
it is a test of physical hardware! What I did assume was that the programmer who might incorporate this test into his own code knows what he's doing. You don't assume anything about RAM until after you've verified what you're hoping to find. Therefore, a RAM sizing test of any kind should ALWAYS be run BEFORE alterations to the RAM's contents are to occur (e.g., installing new character fonts). It's not my problem if some amateur programmer with a half-baked understanding of computer hardware, and limited coding skills, incorrectly utilizes a utility and ends up with baby-puke for a video display.
As for whether the program is to be used in the context of a larger application, any competent 6502 programmer will know how to integrate the VRAM test into his handiwork in a way that makes sense.
Everything about which you seem to be complaining revolves around only one thing: the speed of the test. The
DLCHR sub, which copies 8K from CHARROM to VRAM, takes approximately 780K clocks to complete, resulting in about 800 millisecond SLOW mode performance. Try testing in FAST mode and see what happens. The test should run about 70-80 percent faster. In either case, so what if it does take 800 MS to complete? The test only has to be run once, you know, not every five minutes.
Quote from: Michael Hart on January 24, 2008, 08:42 AM
Anyway, this obviously comes down to a philosophical difference, so I'll drop it. You or others are welcome to discuss the issues, though.
No, this is not a case of a "philosophical difference." It's a case of doing it right. I get so tired of seeing Commodore programmers taking unwarranted shortcuts in their programs and then blaming everything but their code when it doesn't work right. In the world of M/L, doing it right requires work and patience, which never seems to be in adequate supply. I used to write this stuff to make money, and you can best believe I made sure it was right when it shipped. If being right means the VDC RAM test takes a perceptible amount of time (Gee! A whole 800 MS! Why, so much time was wasted, I could've run out and had lunch!), so be it. At least when it's run, the user can depend on it to report reliable results every time and not make a mess of the system in the process. And, if he doesn't like the way it works, the source code is readily available.
Quote from: BigDumbDinosaur on January 24, 2008, 05:43 PM
Okay, let's stop this right now. I'm going to get into your face a bit about this topic, because you are exhibiting an aspect of Commodore computer programming behavior that has annoyed me (and some of my former collaborators) for some 25 years. Please don't take offense, since what I'm going to say is borne out of literally decades of writing software at the machine level.
None taken. I respect and admire your technical knowledge and experience more than realize. Whenever I see a new post by you I look forward to reading it, because I know that you will always have something interesting to say, and most of the time I learn something from you. I can't even pretend to fathom why you include the word "dumb" in your username, as it's probably the least fitting adjective I can think of for you in any of its senses.
Unfortunately for you, I *am* dumb and inexperienced about many things, so if you had any ideas of getting away from the kind of people you've found annoying for the last 25 years, you might as well give that up now.
Quote from: Michael Hart on January 24, 2008, 07:52 PM
Quote from: BigDumbDinosaur on January 24, 2008, 05:43 PM
Okay, let's stop this right now. I'm going to get into your face a bit about this topic, because you are exhibiting an aspect of Commodore computer programming behavior that has annoyed me (and some of my former collaborators) for some 25 years. Please don't take offense, since what I'm going to say is borne out of literally decades of writing software at the machine level.
None taken. I respect and admire your technical knowledge and experience more than realize. Whenever I see a new post by you I look forward to reading it, because I know that you will always have something interesting to say, and most of the time I learn something from you. I can't even pretend to fathom why you include the word "dumb" in your username, as it's probably the least fitting adjective I can think of for you in any of its senses.
Unfortunately for you, I *am* dumb and inexperienced about many things, so if you had any ideas of getting away from the kind of people you've found annoying for the last 25 years, you might as well give that up now.
Assuming I survive tomorrow's blood-letting, I don't plan on going anywhere. If someone bugs me in some way, I make sure they know it. <Grin>
One of the reasons I come here is so I can post for posterity all the things I've learned over the years in working with computers. I'm guessing from what I've seen that despite its age and technical obsolescence, the C-128 is still relatively popular. It is a pretty capable machine, all things considered. In a space of about four years, I focused a lot of attention on that one computer and thus have a pretty good recollection about how it works and so forth. There's a lot I did on it from which others should be able to benefit.
Most of my focus was on using the 128 for business computing, hence heavy development of database work, especially with the Lt. Kernal. Since I was not particularly interested in playing games or doing other recreational computing at the time, I know little about those aspects of software development. My electrical engineering background has been helpful in figuring out how to drive chips like the VDC and CIA.
So I'll try to help out and if I get a bit huffy at times, just remember I'm basically just a big, broken-down old dinosaur who still remembers what it's like to get burned by a hot vacuum tube.
Speaking of vacuum tubes, how about a tube powered guitar amplifier? http://www.veroamps.com (http://www.veroamps.com)