GEOS Technical Reference Notes December, 1987 This document provides some preliminary information about the differences between C64 GEOS and C128 GEOS. It is not intended to be comprehensive; Compatibility with C64 GEOS software ------------------------------------ Most C64 GEOS software will run under the C128 GEOS in 40 column mode. All data files, scraps, fonts, & printer drivers are identical under C64 and C128 GEOS. Input drivers are located at different addresses in the two machines, and hence are incompatible. We have added a new file type, INPUT128, for C128 input drivers. As the deskTop is heavily tied into each OS, we've decided to give the 128 it's own desktop filename, "128 DESKTOP", so as to avoid confusion with the 64's "DESK TOP" file. (The deskTop is of file type "SYSTEM", and can't be renamed by the user). 128 Flags for Applications & Desk Accessories --------------------------------------------- In order for the 128 DESKTOP & other applications to know what files run in what mode, we've adopted a standard that should be used on ALL applications, desk accessories, & auto-execution programs. This flag is located in the header block of each of these programs. Since permanent file names are only 16 bytes long, we have left over 4 bytes that have been unused till now, but we've constantly been setting them to all 0's. The last of these bytes (see OFF128FLAGS) now has meaning to the 128 OS & DeskTop: B7 B6 0 0 runs under 128 GEOS, but in 40 column mode only 0 1 runs under 128 GEOS in 40 and 80 column modes 1 0 DOES NOT RUN under 128 GEOS (deskTop will display dialog box) 1 1 runs under 128 GEOS in 80 column mode only Bits 5 through 0 are unused and should be 0. The 128 GEOS routines LdApplic and LdDeskAcc will return the error #INCOMPATIBLE if these flags in the header block do not allow running in the current mode. Converting 64 GEOS software to run on the C128 ---------------------------------------------- First, you need to decide whether your software is simply going to be able to run in 40 col. mode, or whether it is to run in 40/80 column on the 128 only. 40 col. mode only on 128: 1) Chances are quite good your software already does. 2) If it doesn't, it's probably becuase you access BASIC -- the 128 has a different BASIC, so you'll need to re-write that section of code to first see which OS you're running under, & then use the appropriate BASIC variables & jump entries. 40/80 col. on the C128 only: 1) Set the 128 flag as mentioned above in the save file to $40 2) In 80 column mode, you'll need to widen your menus to accomodate the wider system font. We typically stuff these "right edge" values into the menu structure itself based on the current graphicsMode ($80 is 80 column, $00 is 40) 3) Most of the graphic changes you'll need to make can be accomplished by setting the high bit of every X position or width that you pass to the operating system. The 128 GEOS will ignore this bit if in 40 column mode, and double the value if in 80 column mode, thus automatically retaining the same sized image on the screen. Hence, 50+$8000 is 50 pixels in 40 column mode and 100 pixels in 80 column mode. 4) If you're writing an application, add a "switch 40/80" option under the geos menu. The action for this should be to EOR graphicsMode with $80, store it back, and call the routine SetNewMode. You'll then need to redraw the screen, now in the new graphics mode. 5) Nearly all x positions passed to the C128 GEOS can have the high bit set causing the position to automatically be doubled in 80 column mode. It has been noted that this always results in the low bit of the resulting word being a 0. This can make life difficult, if you desire to fill a pattern to the right edge of the screen, for instance. To solve this problem, I've modified the normalization routine: The 15th bit of the word continues to be the same "double me if 80 col." flag, but the 14th bit now has significance in 80 col. mode only -- it becomes the low bit of the doubled word. So, if you want the right edge of the screen, use the value $C000+319. Sprites ------- The C64 contains a chip to handle sprites in hardware. Unfortunately, this chip is not available on the 128, so the functions of that chip have been simulated in software that is included in the 128 kernal. Most of the capabilities of the VIC chip have been taken care of, and if you are not doing exotic things with sprites your code may work with one or two changes. The major changes include: sprite 0 (the cursor) is treated differently than any other sprite. The code for this beast has been optimized to get reasonably fast mouse response, with a resulting loss in functionality. You cannot double the cursor's size in either x or y. You cannot change the color of the cursor. The size of the cursor is limited to 16-pixels wide and 8 lines high. One added feature is the ability to add a white outline to the picture that is used for the cursor. This allows it to be seen while moving over a black background. For the other 7 sprites, all the capabilities have been emulated except for color and collision detection. In addition, the 64th byte of the sprite picture definition (previously unused) is now used to provide some size info about the sprite. This is used to optimize the drawing code. Here are some problem areas to watch out for: Writing directly to the screen: Since the old sprite were handled with hardware, writing to the screen wasn't a problem. If you do it (system calls NOT included), then call "TempHideMouse" before the write. This will erase the cursor and any sprites you have enabled. You don't have to do anything to get them back, this is done automatically during the next main loop. All sprite picture data: All picture data should be adjusted to include the 64th byte. This byte has size information that is read by the software sprite routines, even if they are garbage values. The format of this byte is: high bit set means that the sprite is no more that 9 pixels wide (this means it can be shifted 7 times and still be contained in 2 bytes). The rest of the byte is a count of the scan lines in the sprite. You can either include this info as part of the picture definition, or stuff it into the right place with some special code. Writing directly to the VIC chip: This is generally ok, since the sprite emulation routines take the position and doubling info from the registers on the VIC chip, with the exception of the x position. The VIC chip allows 9 bits for x positions, which is not enough 640-wide screen. You should write the x position to the global variables "reqXpos0, reqXpos1..." (request x pos). These are full words, in consecutive locations. Better yet, use the "PosSprite" call in the kernel. Reading values from the VIC chip: This is also ok for the status values and for the y position. The x position can be useful also, if you use the PosSprite call. In addition to filling the global variables reqXpos0, etc., this call divides the x position by two and stuffs it into the VIC chip. Using VIC chip collision detection: This is iffy. The chip continues to operate, so if you are using the PosSprite call (see above) collisions should be detected with some loss of accuracy (the low bit). This has not been tested, so if you try it -- report the results here. Writing to the VIC chip (or calling PosSprite, EnablSprite, DisablSprite) at interrupt level: Don't do it. Since the mouse and the sprites are drawn at main loop, this causes subtle, irreproducable timing bugs that are impossible to get out. Known bugs in release 1 of GEOS 128 ----------------------------------- 1) If location $1300 in application space is zero, then sprites in 80 column mode go haywire. All of our current applications that run in 80 column mode have put in a patch for this. Bug is in sprite code. 2) Doubling bitmaps through BitmapClip doesn't work. 3) iBitmapClip needs call to TempHideMouse before being called. ;************************************************************************** ;This file contains additional memory map definitions for applications which ;will run under the GEOS 128 kernal. 12/11/87. ;************************************************************************** ;Memory-management unit in C-128 mmu= $D500 VDC= $D600 ;Address of memory-map configuration register in C-128 config= $FF00 ;Misc addresses: keyreg= $d02f;C-128 keyboard register for # pad & other keys clkreg= $d030;C-128 clock speed register ;Address of input driver MOUSEBASE= $FD00 ENDMOUSE= $FE80 ;Note that the jump table entries for input driver routines have not moved; ;They are still at MOUSEJMP ($FE80). In 128 GEOS, there is one additional ;vector: SetMouse= MOUSEJMP+9;($FE89) ;Jump addresses within disk drivers -- these are only valid for non-1541 ;disk drive types, and for the 128 version of the 1541 driver: Get1stDirEntry= $9030;returns first dir entry GetNxtDirEntry= $9033;returns next dir entry AllocateBlock= $9048;allocates specific block ReadLink= $904B;like ReadBlock, but returns only 1st two bytes ;The following address holds info about the current 128 graphics mode: ;$00 for VIC, $80 for VDC 640*200, and $C0 for VDC 640*400 (not yet supported). graphicsMode= $003f;holds current 128 graphics mode ;Misc vectors: JmpIndX= $9D80;address of routine used by 128 kernal ;----------------------------------------------------------------------------- ;This is a second GLOBAL memory area for GEOS. It is here so that these ;variables may be in the same place in V1.3 as they are running V1.2 with ;the V1.3 deskTop. This allows other input drivers to be auto-booted by ;those who have a V1.2 GEOS KERNAL, but have gotten the V1.3 deskTop via ;a download or up-grade disk. They are EQUATED to be past the local GEOS ;variables, in fact at the end of the GEOS RAM space. Here they must ;permanently reside, for the sake of compatibility. ;Saved value of moby2 for context saving done in dlg boxes & desk accessories. ;Left out of original GEOS save code, put here so we don't screw up desk ;accessories, etc, that know the size of TOTSRAMSAVED above. savedmoby2= $88bb ;copy of reg 24 in VDC for C128 screen80polarity= $88bc ;Screen colors for 80 column mode on C128. Copy of reg 26 in VDC screen80colors= $88bd ;Holds current color mode for C128 color routines. vdcClrMode= $88be ;(4 bytes) 1 byte each reserved for disk drivers about each device ;(each driver may use differently) driveData= $88bf ;Number of 64K ram banks available in Ram Expansion Unit. 0 if none available. ramExpSize= $88c3 ;If RAM expansion is in, Bank 0 is reserved for the kernal's use. This byte ;contains flags designating its usage: ; ; Bit 7: if 1, $0000-$78FF used by MoveData routine ; Bit 6: if 1, $8300-$B8FF holds disk drivers for drives A through C ; Bit 5: if 1, $7900-$7DFF is loaded with GEOS ram area $8400-$88FF by ToBasic ;routine when going to BASIC ; Bit 4: if 1, $7E00-$82FF is loaded with reboot code by a setup AUTO-EXEC ;file, which is loaded by the restart code in GEOS at $C000 if ;this flag is set, at $6000, instead of loading GEOSBOOT. ;Also, in the area $B900-$FC3F is saved the kernal for fast ;re-boot without system disk (depending on setup file). ;This area should be updated when input devices are changed ;(implemented in V1.3 deskTop) sysRAMFlg= $88c4 ;This flag is changed from 0 to $FF after deskTop comes up for the first time ;after booting. firstBoot= $88c5 ;(4 bytes) Current disk type for each drive (copied from diskType) curType= $88c6 ;(4 bytes) RAM bank for each disk drive to use if drive type is RAM DISK ;or Shadowed Drive ramBase= $88c7 ;(17 bytes) Holds name of current input device inputDevName= $88cb ;(18 bytes) Disk name of disk in drive C. (Padded with $a0) DrCCurDkNm= $88dc ;(18 bytes) Disk name of disk in drive D. (Padded with $a0) DrDCurDkNm= $88ee ;(256 bytes) 2nd directory header block, for larger disk capacity drives ;(such as 1571) dir2Head= $8900 ;----------------------------------------------------------------------------- ;************************************************************************** ;This file contains additional jump-table entries for applications which ;will run under the GEOS 128 kernal. 12/11/87. ;************************************************************************** TempHideMouse= $c2d7 SetMousePicture= $c2da SetNewMode= $c2dd NormalizeX= $c2e0 MoveBData= $c2e3 SwapBData= $c2e6 VerifyBData= $c2e9 DoBOp= $c2ec AccessCache= $c2ef HideOnlyMouse= $c2f2 SetColorMode= $c2f5 ColorCard= $c2f8 ColorRectangle= $c2fb ;************************************************************************** ;This file contains additional constant definitions for applications which ;will run under the GEOS 128 kernal. 12/11/87 ;************************************************************************** ;The following equates define the numbers written to the "config" ;register (location $FF00 in C-128). This register controls the memory map ;of the C-128. CIOIN= $7E;60K RAM, 4K I/O space in CRAM64K= $7F;64K RAM CKRNLBASIOIN= $40;kernal, I/O and basic ROM's mapped into memory CKRNLIOIN= $4E;Kernal ROM and I/O space mapped in ;Keyboard equates KEYHELP= 25 KEYALT= 26 KEYESC= 27 KEYNOSCRL= 7 KEYENTER= 11 ;128 screen size constants SCREENBYTEWIDTH= 80 SCREENPIXELWIDTH= 640 ;New GEOS file types: INPUT128= 15;128 Input driver ;New # of file types, including NONGEOS (=0) NUMFILETYPES= 16 ;The following equate can be used as an offset into a file's header block. ;It points to the byte which contains flags which indicate if the program ;will run under C-128 GEOS in 40 and/or 80 column modes. These flags are valid ;for applications, desk accessories, and auto-exec files. ; ;B7 B6 ; 0 0 runs under 128 GEOS, but in 40 column mode only ; 0 1 runs under 128 GEOS in 40 and 80 column modes ; 1 0 DOES NOT RUN under 128 GEOS (deskTop will display dialog box) ; 1 1 runs under 128 GEOS in 80 column mode only OFF128FLAGS= 96 ;disk equates DIR1581TRACK= 40;track # reserved on 1581 disk for directory DRV1581= 3;Drive type Commodore 1581 DRVNETWORK= 15;Drive type for GEOS geoNet "drive" ;equate for error value which indicates an attempt has been made to load ;an application which cannot be run under the current C128 graphics mode. INCOMPATIBLE= 14