CCCCCC HH HH AAAA CCCCC KK KK IIIIII NN NN GGGG CC ==== HH HH AA AA CC KK KK II NNN NN GG CC === HH HH AA AA CC KKKK II NN NNNN GG CC HHHHHHHH AA AA CC KKKK II NN NNNN GG GGG CC === HH HH AAAAAAAA CC KK KK II NN NNN GG GG CC ==== HH HH AA AA CC KK KK II NN NN GG GG CCCCCC HH HH AA AA CCCCC KK KK IIIIII NN NN GGGGG Volume 1 - Issue 2 - April 22, 1992 ============================================================================== Editor's Notes: by Craig Taylor (duck@pembvax1.pembroke.edu) Eeegh! - When I first started this I never realized how much work it'd be. I'm glad of the reception it's gotten from the Commodore community at large. I'd like to thank each of the author's in this issue and last for their work they've put into it as well as their time. Please note that all files, documentation etcetera associated with C= Hacking and whatnot contained within are also now available at tybalt.caltech.edu via anonymous ftp under the directory /pub/rknop/hacking.mag. Any updates to files contained within or corrections will be posted there as well as mentioned here. Currently it has the correct 1st issue and (soon to be) 2nd issue. Also Robert Knop's file bmover.sfx is there for the Banking Geos article in this issue. It seems as if we're averaging about 2 months for each issue and hopefully we'll keep that rate during the summer but due to an internship (I'll hopefully get) I may not have net access during the summer. In that case it'll be delayed until after I get back to school in the fall. Also, if you've got any ideas for articles or have written a program that is unique that you'd be interested in documenting and p'haps letting other people see some of the tricks of the trade then please send any queries to duck@pembvax1.pembroke.edu. ****************** WARNINGS, UPDATES, BUG REPORTS, ETC... ********************* Please note that in the last issue when the undocumented opcodes were discussed that they are _VERY NON-STANDARD_. And any future accelerator boards for the C=128 or C=64, in all likelehood, _will not work_. Zip's board [when are they ever gonna finish it?] for the C=128 will be based on a similair processor to the 8502 and is practically guarenteed not to work with the undocumented op-codes. If you plan to release any ML programs for general use PLEASE be aware that they may be in-compatible with future systems. ============================================================================ Note: Permission is granted to re-distribute this "net-magazine", in whole, freely for non-profit use. However, please contact individual authors for permission to publish or re-distribute articles seperately. *** AUTHORS LISTED BELOW RETAIN ALL RIGHTS TO THEIR ARTICLES *** ============================================================================ In this edition we've got the following articles: Learning ML - Part 2 Yes, the infamous learning machine langauge tutors by Craig Taylor (duck@pembvax1.pembroke.edu). In this session we examine indexed addressing and it's usefulness in printing strings of characters. 8563 : An In-Depth Look This article documents and details the 8563 in-depth. It covers all available registers, documents their functions and suggested methods of getting certain effects. Also covers how to read and write to 8563 registers as well as read the 16k or 64k of memory that contains the VDC char-set, screen memory etc. Written by Craig Taylor (duck@pembvax1.pembroke.edu). The Poor Man's Way to Getting Files from MS-Dos Diskettes Now there's a way to transfer files of any length from MS-Dos diskettes using a public domain program that will only read files of 43k or less and a IBM program to split the files up. There are better ways, but if you don't want to pay for Big-Blue Reader this is one method to go. Written by Mark Lawrence (9152427D@Levels.UniSa.Edu.Au). Banking on Geos GEOS 128, being an extended and expanded version of GEOS 64, provides a contiguous block of application space in a single RAM bank. The "standard" programming documentation makes few references to the use of other banks in GEOS. This article describes accessing other RAM banks (including RAM banks 2 and 3 for 256K expanded 128's) under GEOS128, using both the GEOS Kernal routines and more direct methods. By Robert Knop (rknop@tybalt.caltech.edu). Dynamic Memory Allocation Written by Craig Bruce (csbruce@ccnga.uwaterloo.ca) this article examines how to implement and use dynamically allocated memory that will allow your programs to better utilize all of the available memory on your C=128, including expansion memory. These routines are extracted from the Zed-128 program which is a text editor that can edit 600KByte files on a 512K expanded 128. ============================================================================= Beginning ML #2 by Craig Taylor (duck@pembvax1.pembroke.edu) Last time we introduced the definition of what exactly Machine Language / Assembly Language is along with an example of clearing the screen in Machine Language. Now, in this issue let's print my name (and later your name). Looking at the code from last time the following assembly source jumps to mind: ------------ print_1.asm: lda #147 ; clr/screen code jsr $ffd2 ; print lda #'C' ; code for ascii "C" jsr $ffd2 ; print lda #'r' jsr $ffd2 lda #'a' jsr $ffd2 lda #'i' jsr $ffd2 lda #'g' jsr $ffd2 lda #32 ; code for space jsr $ffd2 lda #'T' ; print my last name.... jsr $ffd2 . . (ad naseum...) . rts ---------- Now, for short strings like "HI!" that might be fine but if your name is something like "Seymour Johnson the third" it can get a little bit ridiculous in terms of the amount of memory and the amount of typing (eegh! - typing!) involved. There's an easier way. It's called indexed addressing. What is this you say? Let's first take a look at the above program using indexed addressing and then explain it. ------------ print_2.asm ldy #$00 loop lda string,y jsr $ffd2 iny cpy #numchars bne loop rts string .byte 147 .ascii "Craig Taylor" numchars = *-string ------------ Hmm, looks a little bit confusing 'eh? What we're doing is using the register y to act as a pointer to grab the y'th character in what is at memory location STRING. If y is 0 then we'll get string+0 which happens to be a 147. The .byte and .ascii directives are not real instructions the computer understands. What happens is that your assembler sees that you want data put at those locations so it convert 147 and "Craig Taylor" to numbers and puts them at the proper locations, relieving you the burden of doing it. The numchars = *-string looks confusing at first... obviously, numchars stands for the number of characters we need to print out but how is it being figured? Most assemblers keep the current location in memory it's assembling to in something called a program counter of PC. Most assemblers also will let you have the value at assembly time by referencing it using the "*" symbol. "string" is already a symbol that has been set an address in memory and after assembling the .byte and .ascii instruction "*" will be equal to the next address that the assembler would put any instructions at, had we had any. Now, *-string basically is saying to the compiler, look, take the current program counter (where it's assembling to) and subtract it from where the symbol string starts at (which it just assembled a while back). This should be then, our number of characters we have. WALK-THROUGH: Register Y is initially set to zero in the first instruction, as we want to begin with the first character. The first character is at string+0, not string+1. This may seem a little bit odd at first, but try thinking of it this way: Take, for example, 3 diskettes. Put them in a row and call the one on the left "string" (or some other name). Then point at "string+1", "string+2".. Notice there's no "string+3" even tho' there's 3 diskettes? This may seem a little bit strange at first, but after thinking about it a while you'll begin to understand. In machine / assembly language, you typically count starting from zero, in the real world, typically from one. The lda string,y instruction is telling the computer to reference string as if it was an array, get the byte at location string + y, or for you basic programmers thinking of string as an array of bytes (with no bounds checking) string[y]. Thus, the accumulator is equal to the yth byte starting from the location string is defined to be. We then call the routine Commodore so graciously provided for us that prints out the contents of the accumulator. Now, some routines, as we'll see in other editions, are not so nice and may change the value of the accumulator, the x and y registers. However, Commodore was extra nice and the routine at $ffd2 is guaranteed not to change any of the registers. The routine then "iny". What is this? It "INcrements the Y register". INX will "INcrement the X register". The X and Y register can not have any math performed on them other than increment and decrement operations (ie: adding one and subtracting one). The only register that allows addition or subtraction is the accumulator. However, in this case we just want y to point to the next character, the next byte so "INY" serves us fine. We then "ComPare Y" register to the number of characters in the string. Notice the # sign. If we hadn't have had that there, it would've tried to look at whatever memory location numchars was defined for. Numchars was set up to hold the number of characters in the string, not be a pointer for a memory location. Now that we've compared it, we "Branch if the last comparison was Not Equal" back to where loop is at (in this case, where we load a with character again). If it was equal we fall through to the RTS where we return from our little program. Basically, we've got something like the following flowchart: _______ / START \ \_______/ | \|/ +-----------------+ | Set Index (Y) | | first character | +-----------------+ | \|/ +-------------------+ | Get the character | / | pointed to by |<------------------+ | the index(Y) | \ | +-------------------+ | | | \|/ | +-------------+ | | Print it | | +-------------+ | | | \|/ | +------------------------+ | | Increment the Index(Y) | | +------------------------+ | | | \|/ | /\ | /= \ | /# of\ | /chars?\ | /to print\___no,not =_____------------->+ \??? / \ / \ / \ / \/ | \|/ _____ / END \ \_____/ Indexed addressing is used *very* often in assembly language. Try playing with the second program and experiment with it until you understand fully what is going on. Next time we'll look at how to access some of the diskette routines and to display a file on disk. =============================================================================== An In-Depth Look at the 8563 Video Chip on the C= 128 ----------------------------------------------------- by Craig Taylor (duck@pembvax1.pembroke.edu) Due to the article in the last issue by Craig Bruce (csbruce@ccnga.uwaterloo. ca) and some letters from people asking about how the 8563 Video Chip works and more technical information this article will attempt to present as much detail as possible on the 8563 chip & it's various capibilities. --------------------- ! Hardware Aspects: ! --------------------- The following is a physical layout of the 8563 and the available pin outs: +------------------+ 42 o_|DD7 VDD CS DA7|_o 33 DA0-DA7 - Address Bus for Ram 41 o_|DD6 DA6|_o 32 DD0-DD7 - Data Bus for Ram 40 o_|DD5 DA5|_o 31 D0 - D7 - Data Bus 8563 / Cpu 39 o_|DD4 DA4|_o 30 CS /CS - Chip Selection Pin 38 o_|DD3 DA3|_o 29 /RS - Register Select 36 o_|DD2 DA2|_o 28 R/W - Data Direction for Data Bus 35 o_|DD1 DA1|_o 27 INIT - Initialize internal latches 34 o_|DD0 DA0|_o 26 DISPEN - (Unused) Display Enable | | RES - (Unused) Reset all scan cnts | | TST - (Unused) Test purposes only 10 o_|D7 /CAS|_o 48 DR/W - Local Dram Read/Write 11 o_|D6 /RAS|_o 47 /RAS - Row Address Strobe 13 o_|D5 DR/W|_o 21 /CAS - Column Address Strobe 14 o_|D4 | DCLK - Video Dot Clock 15 o_|D3 R|_o 46 CCLK - (Unused) Character Clock 16 o_|D2 G|_o 45 LP2 - Input for Light Pen 17 o_|D1 B|_o 44 HSYNC - Horizontal Sync 18 o_|D0 I|_o 43 R,G,B,I - Pixel Data Outputs | | | | 8 o_|/RS | 7 o_|/CS | 9 o_|R/W VSYN|_o 20 23 o_|/RES HSYN|_o 3 | | | CCLK|_o 1 25 o_|/LP2 DISPEN|_o 19 | | | TST|_o 24 2 o_|/DCLK VS5 INIT|_o 22 +------------------+ !12 o Taken from Pg. 596-8 C=128 Programmer's Reference Manual Publ. Feb 1986 Bantem Books +-----------------------------+ | How Commodore Hooked It Up! | +-----------------------------+ Now, the 8563 is hooked up to the computer via the following method: +---------------------+ | | +--------+ +-------+ |Computer Memory | | 8563 | |16k or | | (RAM) | | | % | 64k | | |___$d600_____|da0-7 | % |VDC RAM| | | | | % | | | |___$d601_____|dr0-7 | % |(Screen| | | ( /rs) | d0-7|___| Mem) | +---------------------+ +--------+ +-------+ Confusing 'eh? (The %'s represent control signals that also are used).. What basically happens is that every time the computer wants to access the 8563 to program or change one of it's numerous registers it has to store the register number to $d600, then loop until the 7th bit of $d600 changes to a 1. Once this is done, you can then read or write a value to/from $d601. Commodore also employed the MMU (Memory Management Unit) to manipulate pages of memory and thus, the 8563 only shows up in the I/O page (usually referenced as Bank 15 or a value of $00 in the MMU Register at $ff00) or in pages that the I/O section of memory is enabled. The register at $d600 in the I/O space of the C=128 is laid out as follows: Bit Position: 7 6 5 4 3 2 1 0 Status LightPen VBlank -----Unused---- ------Version #-------- When a value is placed in $d600 instead of putting the value in Status, LightPen bits etc, the value reflects which register # is requested. Bit 7 of this register (Status) will then return a binary 1 when $d601 reflects the actual value of the register just poked to $d600. (See the ML routines for storing and reading values to/from registers at the end of this article). When a value is first place in this register, $d600 bit 7 is equal to a zero. Bit 6, is used to indicate when new values have been latched into the lightpen registers (16-17). Bit 5, VBlank refers to when the 8563 is in the period known as "Vertical Blanking Period". Usually, however this bit is seldom referred to as updating the 8563 is usally too slow to make use of this for any special effects. Bits 0-2 return a version # of which %000 and %001 are the known versions out. Early 128's will contain the value of $0 while later 128's will contain the value of $1. Note that there are slight differences between the 8563's, in that register 25 (horizontal smooth scoll register) requires different settings. The register at $d601 returns the value of register # that has been written into $d601 (when bit 7 of $d600 = %1). Note that storing a value here will also do a write into the register # selected. (Refer to the ML routines for storing and reading values to/from registers at the end of this article for an example). ------------------------ | Register Definitions | ------------------------ Reg# 7 6 5 4 3 2 1 0 Description Notes ------- ---- ---- ---- ---- ---- ---- ---- ---- ------------------------ ----- 0 HzT7 HzT6 HzT5 HzT4 HzT3 HzT2 HzT1 HzT0 Horizontal Total ^1 1 HzD7 HzD6 HzD5 HzD4 HzD3 HzD2 HzD1 HzD0 Horizontal Displayed ^1 2 HzS7 HzS6 HzS5 HzS4 HzS3 HzS2 HzS2 HzS0 Horizontal Sync Position ^1 3 VSW3 VSW2 VSW1 VSW0 HSW3 HSW2 HSW1 HSW0 Vert/Horiz. Sync Width ^2 4 VeT7 VeT6 VeT5 VeT4 VeT3 VeT2 VeT1 VeT0 Vertical Total ^3 5 .... .... .... VeA4 VeA3 VeA2 VeA1 VeA0 Vertical Total Fine Adju ^3 6 VeD7 VeD6 VeD5 VeD4 VeD3 VeD2 VeD1 VeD0 Vertical Displayed ^3 7 VeS7 VeS6 VeS5 VeS4 VeS3 VeS2 VeS1 VeS0 Vertical Sync Position ^2 8 .... .... .... .... .... .... Ilc1 Ilc0 Interlace Mode ^4 9 .... .... .... CTV4 CTV3 CTV2 CTV1 CTV0 Character Total Vertical ^5 10 .... CrM1 CrM0 Css4 Css3 Css2 Css1 Css0 Cursor Mode/ Start Scan ^6 11 .... .... .... Ces4 Ces3 Ces2 Ces1 Ces0 Cursor End Scan ^6 12 Ds15 Ds14 Ds13 Ds12 Ds11 Ds10 Ds09 Ds08 Display Start Adrs (Hi) ^7 13 Ds07 Ds06 Ds05 Ds04 Ds03 Ds02 Ds01 Ds00 Display Start Adrs (Lo) ^7 14 Cp15 Cp14 Cp13 Cp12 Cp11 Cp10 Cp09 Cp08 Cursor Position (Hi) ^7 15 Cp07 Cp06 Cp05 Cp04 Cp03 Cp02 Cp01 Cp00 Cursor Position (Lo) ^7 16 LpV7 LpV6 LpV5 LpV4 LpV3 LpV2 LpV1 LpV0 Light Pen Veritcal ^8 17 LpH7 LpH6 LpH5 LpH4 LpH3 LpH2 LpH1 LpH0 Light Pen Horizontal ^8 18 Ua15 Ua14 Ua13 Ua12 Ua11 Ua10 Ua09 Ua08 Update Address (Hi) ^9 19 Ua07 Ua06 Ua05 Ua04 Ua03 Ua02 Ua01 Ua00 Update Address (Lo) ^9 20 At15 At14 At13 At12 At11 At10 At09 At08 Attribute Start Adrs (Hi) ^7 21 At07 At06 At05 At04 At03 At02 At01 At00 Attribute Start Adrs (Lo) ^7 22 HcP3 HcP2 HcP1 HcP0 IcS3 IcS2 IcS1 IcS0 Hz Chr Pxl Ttl/IChar Spc ^A 23 .... .... .... VcP4 VcP3 VcP2 VcP1 VcP0 Vert. Character Pxl Spc ^5 24 BlkM RvsS Vss5 Vss4 Vss3 Vss2 Vss1 Vss0 Block/Rvs Scr/V. Scroll ^9^B^C 25 Text Atri Semi Dble Hss3 Hss2 Hss1 Hss0 Diff. Mode Sw/H. Scroll ^D,^E 26 Fgd3 Fgd2 Fgd1 Fgd0 Bgd3 Bgd2 Bgd1 Bgd0 ForeGround/BackGround Col ^F 27 Rin7 Rin6 Rin5 Rin4 Rin3 Rin2 Rin1 Rin0 Row/Adrs. Increment ^G 28 CSa2 CSa1 CSa0 RamT .... .... .... .... Character Set Addrs/Ram ^H,^I 29 .... .... .... UdL4 UdL3 UdL2 UdL1 UdL0 Underline Scan Line ^6 30 WdC7 WdC6 WdC5 WdC4 WdC3 WdC2 WdC1 WdC0 Word Count (-1) ^9 31 Dta7 Dta6 Dta5 Dta4 Dta3 Dta2 Dta1 Dta0 Data ^9 32 BlkF BlkE BlkD BlkC BlkB BlkA Blk9 Blk8 Block Copy Source (hi) ^9 33 Blk7 Blk6 Blk5 Blk4 Blk3 Blk2 Blk1 Blk0 Block Copy Source (lo) ^9 34 DeB7 DeB6 DeB5 DeB4 DeB3 DeB2 DeB1 DeB0 Display Enable Begin ^J 35 DeE7 DeE6 DeE5 DeE4 DeE3 DeE2 DeE1 DeE0 Display Enable End ^J 36 .... .... .... .... Drm3 Drm2 Drm1 Drm0 DRAM Refresh Rate ^K +-----------------+ | Register Usage: | +-----------------+ ^1 : Register #0: Horizontal Total --- Register #1: Horizontal Displayed Register #2: Horizontal Sync Pulse These two register function to define the display width of the screen. Register 0 will contain the number of characters minus 1 between sucessive horizontal sync pulses, the horizontal border and the interval between horizontal sync pulses. The normal value for this is usually set to 126. Register 1 specifies how many of the positions as specified in register 0 can actually be used to display characters. The default value for this is 80. The VDC can take values less than 80 and thus, will only display that many characters. A useful effect can be a sweep from the right by incrementing the value here from 1 to 80. Register #2 specifies the starting character position at which the vertical sync pulse begins. Thus, it also determines where on the active screen characters appear. A default value of 102, increasing the value moves the screen to the left, decreasing it moves it to the right. ^2 : Register #3: Vertical / Horizontal Sync Position. ---- Register #7: Vertical Sync Position In Register 3, Bits 0-3 of this register specifies the horizontal sync width and should be equal to 1 + the number of pixels per character. Thus, the value here is normally 1+8 or 9. Bits 4-7 of register 3 specify the vertical sync width and normally contains a value of 4. For interlace sync and video mode, use a value that is twice the number of scan lines desired. Register #7 allows for adjustment of where the vertical sync will be generated allowing shifting of the actual display up and down. Normally, a value of 4, decreasing the value will move the screen down, increasing it will appear to move it upwards. ^3 : Register #4: Vertical Total ---- Register #5: Vertical Total Fine Adjust Register #6: Vertical Displayed Register #4 of this register determines the total number of screen rows, including the rows for the active display, and the top and bottom borders in addition to that of the vertical sync width. The value held here is normally a value of 32 for NTSC systems (US Standard) or 39 for PAL(European) systems. Register #5 holds in bits 0-4 a "fine-adjust" where any extra scan lines that are necessary to make up the display can be specified here. The value here is normally a 0 in both the NTSC and PAL initializations by the kernal and bits 5-7 are unused, always returning a binary 1111. Register #6 specifies the total number of the vertical character positions (as set in Register 4) that can be used for actual display of characters. Thus, this register usually holds a value of 25 for a standard 25-row display. ^4 : Register #8: Interlace Mode Control ---- Register 8 allows control of various display modes the 8563 can generate. Bits 0 and 1 are the only bits used in this register, the rest always reading a binary 1. Bits 0 and 1 are configured as follows: Binary %00, %10 - NonInterlaced Mode %01 - Interlaced Sync %11 - Interlaced Sync and Video Note that the default value is $00 which is standard, non-interlaced. Interlaced sync draws each horizontal scan line twice but appears to suffer from an annoying jitter due to how it is drawn. Interlaced Sync and Video draws twice as many lines, thus doubling the resolution. However, it also suffers from jitter and that is why most monitors suffer horribly when using programs that support more than 30 rows. Note that for interlaced sync and video, the following registers will need to be changed: #'s: 0,4,6,7,8. ^5 : Register #9: Total Scan Lines Per Character ---- Bits 0-4 of this register are the only relevant ones, the rest returning a binary 1. Bits 0-4 determine the character height in scan-lines of displayed characters and allow up to scan-line heights of 32 scan lines. The VDC normally sets aside 16 bytes for each character (normally, each byte is equivlent to 1 scan line) so the value here could be increased to 16-1 and a double-height character set could be loaded in. Note, however that values less than 16 will tell the VDC to use a 8,192 byte character set (normal) while specifying values greater than 16 will make it use 32 bytes per character even if some of the bytes are not used. ^6 : Register #10: Cursor Mode / Start Scan Line ---- Register #11: Cursor End Scan Line. Register #29: UnderLine Scan Line Control. These registers allow the user to specify the cursor blink mode, as well as the starting and ending scan lines for the cursor (allowing a full solid, an underline, Bits 0-4 of regiseter #10 determines the scan line within each position for the top of the cursor. Normally, this value holds a value of 0 for the block cursor, or a value of 7 for the underline cursor. Bits 5-6 of Register 10 specify the blink rate for the cursor. A value of %00 specifies no blink, ie: a solid cursor. A value of %01 specifies no cursor, a value of %10 specifies a flash rate of 1/16 the screen refresh rate, while a value of %11 specifies a flash rate of 1/32 the screen refresh rate. Note that bit 7 of Register 10 is unused and normally returns a binary 1. Register 11 specifies the bottom scan lines in bits 0-4, the other unused bits returning a binary 1. The value held in these bits usually is 7 for the block and underline cursor modes in the normal 128 editor. Register #29 is used to indicate where the scan line is "set" in the character. The "underline" is only 1 pixel tall and thus, this location just indicates the start and end location in pixels, similair to registers #10 and #11 being the same value. Note that bits 5-7 of this register is unused and normally return a binary 1. ^7 : Register #12: Display Start Address (Hi) ---- Register #13: Display Start Address (Lo) Register #14: Cursor Position (Hi) Register #15: Cursor Position (Lo) Register #20: Attribute Start Addrs (Hi) Register #21: Attribute Start Addrs (Lo) Note first, that all of these registers are grouped in Hi byte, Lo byte order which is usually different from the 6502 convention of low byte, hi byte (ie: in normal 6502 ml, $c000 is stored as $00 $c0, however in the 8563 it would be stored as $c0 $00). Registers 12 and 13 determine, where in VDC memory the 8563 is the start of the screen. Incrementing this value by 80 (the number of characters per line) and with a little additional work can provide a very effecient way of having a screen that "seems" to be larger than just 80x25. The cursor position in registers 14 and 15 reflect the actual character in memory that the cursor currently lies over. If it's not on the display screen, then it is not displayed. Registers 20 and 21 reflect where in the 8563 memory attribute memory is held. Attribute memory refers to the character attributes such as flash, inverse video, color etc that can be set for each character. ^8 : Register #16: Light Pen Vertical ---- Register #17: Light Pen Horizontal These registers return the light pen position and refer to the actual character positions on screen (ie: values ranging from 1..25 for vertical). The horizontal reading will not corrospond exactly to character positions, but will range from values of 27-29 to 120 depending on the edge of the screen. It's recommended that the horizontal character position is given more tolerance than the vertical light pen position for this reason. ^9 : Register #18: Update Address (Hi) ---- Register #19: Update Address (Lo) Register #24:7 Copy / Fill Bit Register #30: Word Count(-1) Register #31: Data Register #32: Block Copy Src (Hi) Register #33: Block Copy Src (Lo) These registers allow control and manipulation of the 16k or 64k block within the 8563 memory. Registers 18 and 19 point to where in VDC memory the next read or write will take place from. Register 30 specifies the number of bytes - 1 to copy or fill depending on bit # 7 of register #24. Normally, the 8563 will automatically perform the designated operation (of what bit 7 of register #24 says) when register #31 (the data byte) is written to. Registers 18 and 19 automatically update upon read or write, so that is why register #30 specifies a value 1 less than what is actually needed. Register #31, as already mentioned is the byte to write for register #30 times (or copy from Register#32 / #33). If register #24, bit 7 is specified as a binary 1 then the memory is copied from the address in VDC memory pointed to by registers #32 and #33. ^A : Register #22: Character Horizontal Size Control ---- Bits 0-3 of this register determines how many horizontal pixels are used for each displayed character. Values greater than 8 here result in apparent gaps in the display. Inter-character spacing can be achieved by setting this value greater than that of bits 4-7. Bits 4-7 determine the width of each character position in pixels. Thus, while bits 0-3 allocate n-pixels, bits 4-7 specify how many of those pixels are used for character display. ^B : Register #24:5 Reverse Screen Bit ---- Register #24:6 Blink Rate for Characters. Bit #6 specifies for the VDC for all pixels normally unset on the VDC screen to be set, and all set pixels to be unset. Bit #5 specifies the blink rate for all characters with the blink attribute. Setting this to a binary 1 specifies a blink rate of 1/32 the refresh rate, while a binary 0 is equivlant to a blink rate 1/16th of the refresh rate. ^C : Register #24:0-4 Vertical Smooth Scroll ---- The 8563 provides for a smooth scroll, allowing bits 0-4 to function as an indicator of the number of bits to scroll the screen vertically upward. ^D : Register #25:7 Text or Graphics Mode Indicator Bit ---- Register #25:6 Monochrome Mode Bit Register #25:5 Semi-Graphics Mode Register #25:4 Double-Pixel Mode The 8563 allows the implementation of a graphics mode, in where all of the 16k of the screen may be bit-mapped sequentially resulting in a resolution of 640x200 (see Craig Bruce's 8563 Line-Plotting routine in the first issue for a more detailed explanation of this feature). Setting this bit to 1 specifies graphics mode, binary 0 indicates text mode. Bit 6 indicates to the 8563 where to obtain its color information etc, about the characters. Bit 6 when it is a binary 0 results in the 8563 taking it's color information from bits 4-7 of register 26. When this bit is a binary 1, the attribute memory is used to obtain color, flash, reverse information. Also note than when this bit is a binary 1 that only the first of the two character sets is available. Bit #5 indicates a semi-graphics mode that allows the rightmost pixel of any characters to be repeated through-out the intercharacter spacing gap. Activating it on the normal display will result in what appears to be a "digital" character font. The 8563 with bit #4 allows a pixel-double feature which results in all displayed horizontal pixels having twice their usual size. Thus, a 40 column screen is easily obtainable although the values in registers #00-#02 must be halved. ^E : Register #25: Horizontal Smooth Control ---- This register is analogous to register #24 Vertical Smooth Control and functions similairly. Increasing this bits moves the screen one pixel to the right, while decreasing them moves the screen one pixel to the left. ^F : Register #26: ForeGround / BackGround Color Register ---- This register, in bits 0-3 specifies the background color of the display while bits 4-7 specify the foreground character colors when attributes are disabled (via bit 6 of register #25). Note, these are not the usual C= colors but are instead organized as follows: Bit Value Decimal Value Color ---------------------------------- +-----------------------------+ %0000 0 / $00 Black | Note: Bit 0 = Intensity | %0001 1 / $01 Dark Gray | Bit 1 = Blue | %0010 2 / $02 Dark Blue | RGBI Bit 2 = Green | %0011 3 / $03 Light Blue | Bit 3 = Red | %0100 4 / $04 Dark Green | | %0101 5 / $05 Light Green +-----------------------------+ %0110 6 / $06 Dark Cyan %0111 7 / $07 Light Cyan %1000 8 / $08 Dark Red %1001 9 / $09 Light Red %1010 10 / $0A Dark Purple %1011 11 / $0B Light Purple %1100 12 / $0C Dark Yellow %1101 13 / $0D Light Yellow %1110 14 / $0E Light Gray (Dark White) %1111 15 / $0F White ^G : Register #27: Row Address Display Increment ---- This register specifies the number of bytes to skip, when displaying characters on the 8563 screen. Normally, this byte holds a value of $00 indicating no bytes to skip; however typically programs that "scroll" the screen do so by setting this to 80 or 160 allowing the program to then alter the Screen Start (Registers #12 and #13) and appear to "scroll". Note the normal C= 128 Kernal Screen Editor does not support this function. ^H : Register #28:7-5 Character Set Address ---- These bits indicate the address of screen memory * 8k. Thus the values in these bits may be multiplied by 8192 to obtain the starting character set position (normall these bits hold a value of $01 indicating the character set begins at 8192). Note that the character set is not in ROM, but is usually copied to 8192 when the computer is first turned on and the 8563 is initialized. (Examine the INIT80 routine at $CE0C in bank 15). ^I : Register #28:4 Ram Chip Type ---- This bit specifies whether 16k or 64k of RAM has been installed. Note, however that this value may not reflect future upgrades from 16k to 64k. It is best, if a program is dependant on 64k to write to an address > 16k and see if it is mirrored at any other location in another section of memory. This bit has a binary value of 0 if 16k or 1 if 64k RAM. ^J : Register #34: Display Enable Begin ---- Register #35: Display Enable End The 8563 can extend it's horizontal blanking interval to blank a portion of the displayed screen. The value in register #34 determines the rightmost blanked column, and register #35 determines the leftmost blanked column. Note that a value of 6 usually corresponds to the leftmost column of the screen, while a value of 85 corresponds to the rightmost column. This feature is useful for "inside-out" wraps in which both the right and left margin can close-in on text, the text can be cleared, these values reset etc... ^K : Register #36: Refresh Cycles per Scan Line ---- This register in bits 0-3 allows the user (if he had any reason) to specify the number of refresh cycles for memory for the ram. Setting this value too low may cause the RAM to not remember all the information. Changing this value gives some advantage, in terms of display speed increases but is not advised. The value normally held here is $05, for five refresh cycles per scan line. +--------------------------+ | 8563 Memory Organization | +--------------------------+ Normally, the extra memory of the C=128's equipped with 64k goes unused (48k worth) unless programs like Basic-8 etc, take advantage of it. There are various mod files describing the upgrade from 16k to 64k and it is _strongly_ advised (although the author has not yet done so) and be aware that ***OPENING YOUR COMPUTER JUST TO LOOK, YOU MAY MESS IT UP*** and it is _strongly_ advised that you contact a person experienced with electronics to perform the upgrade for you. Note also that some mail order companies are offering an "up-grade board" which plugs into the 8563 slot and does not involve desoldering the RAM chips. Now, the 8563 uses the 16k of memory (it ignores the extra 48k of memory when it's got 64k, thus the following applies also to the 8563's equipped with 64k of memory) and normally, has the following memory map: $0000 - $07ff - Screen Memory $0800 - $0fff - Attribute Memory $1000 - $1fff - Unused $2000 - $2fff - UpperCase / Graphic Character Set (Char Set #1) $3000 - $3fff - LowerCase / UpperCase Character Set (Char Set #2) +---------------------------+