
STARDISK 1
----------

FERG BRAND
JUNE 1986

     All you ever wanted to know about the STARCARD!

     Here is the approach I recommend to this disk:

1. Read the file STAR.DOC
     This   describes   the  way  the  STARCARD  and  the   APPLE 
communicate with each other.
     Files associated with chapter 1 are:
	  RDTEST.COM
	  WRTEST.COM
	  RUNTEST.COM
	  SBOOT.COM
	  SCRASH.COM
	  C6TEST.COM
	  C7TEST.COM
     Files associated with chapter 2 are all on the DOS 3.3  side 
of this disk.
	  RDTEST.DOS
	  WRTEST.DOS
	  IDTEST.DOS
	  READ, READ/BIN, CALL -151

2. Read the file STAR1.DOC
     This  describes  how  drivers are loaded and how  to  modify 
SFTVIDEO.DVR (on your STARCARD utility disk) for:
	  EPSON APL (printer) card in slot 1
	  ZARDAX shift and control key mods

3. Read the file STAR2.DOC
     This  describes  the drivers included on the disk  that  you 
could use during INSTALL. Briefly though:
	  SFTVIDEP.DVR is SFTVIDEO.DVR modified for the EPSON APL 
(printer) card in slot 1.
	  SAT128K.DVR lets you use a SATURN 128K ramcard in  slot 
0 as a ramdisk (G:). STAR2.DOC tells you how to alter this if the 
ramcard is in a different slot.
	  DIG128K.DVR lets you use a DIGITEK 128K ramcard in slot 
0 as a ramdisk (J:).
	  BUFFRAM.DVR  must  be used instead of  BUFFER.DVR  when 
using  the ramcard in slot 0.  Otherwise both the printer  buffer 
driver  and  the  ramdisk driver will try and use bank 1  of  the 
ramcard at the same time.
	  MEM32K.DVR lets you use 16K of memory plus the language 
card as a 32K ramdisk (H:) instead of as a printer buffer. Do not 
use BUFFER.DVR with this. (The printer will still work though.)
	  MEM16K.DVR is for those with a 48K APPLE II+ without  a 
language  card.  It lets you use 16K of memory as a ramdisk  (I:) 
instead of as a printer buffer. Again, do not use BUFFER.DVR with 
this. 

COMMUNICATION BETWEEN STARCARD AND APPLE
----------------------------------------
----------------------------------------

FERG BRAND
JUNE 1986


INTRODUCTION
------------

     When  the  STARCARD* is operating,  you have  two  computers 
(your  original APPLE and the STARCARD) racing along at different 
speeds  at the one time.  Occasionally they need to talk  to  one 
another.  The APPLE looks after the keyboard, the monitor and the 
disk drives.  So,  for example, if a key is pressed, the STARCARD 
must  listen to the APPLE and conversely,  if a message has to be 
sent to the screen, the APPLE must listen to the STARCARD.

     The  aim  of  this  document is to show  you  how  to  write 
programs   that  manipulate  the  APPLE  while  in  the  STARCARD 
operating system and vice-versa.


     *The  STARCARD,  also known as the APPLI-CARD,  is  made  by 
Personal Computer Products, Inc., USA.


CHAPTER ONE
-----------
HOW THE STARCARD TALKS TO THE APPLE
-----------------------------------


     Let  us look in detail at the way the STARCARD  communicates 
with the APPLE and create some short prorams which will serve  as 
models for your more ambitious attempts.

     Much  of  the hard work has been done for us and there is  a 
cluster  of routines that are resident in the  STARCARD's  memory 
that we can use. To use them, we must

     1. Send the command number to the APPLE, then
     2. Send any parameters that are required.

     There are three important commands:

     #1 READ from APPLE memory

     #2 WRITE to APPLE memory

     #3 RUN a subroutine located in APPLE memory

     To  send  the commands,  parameters and strings of data  and 
receive data,  we make use of six subroutines located in STARCARD 
memory.

     RDHSTBYTE at $FFE0 reads one byte from the APPLE
     RDHSTWORD at $FFE6 reads two bytes, i.e., one word, from the 
APPLE
     RDHSTBYTS at $FFEC reads a number of bytes from the APPLE

     WRHSTBYTE at $FFE3 writes one byte to the APPLE
     WRHSTWORD at $FFE9 writes one word to the APPLE 
     WRHSTBYTS at $FFEF writes a number of bytes to the APPLE

     (I   have  used  the  official  STARCARD  names  for   these 
subroutines. The HST refers to the host computer, i.e., the APPLE 
computer.)

     EXAMPLE  1.  Read from APPLE's F8 ROM and deposit it in  the 
STARCARD memory starting at $3000.

     I used ZSID,  a Z80 version of DDT,  and wrote these in  Z80 
assembly  language using the A(ssemble) option.  If you are using 
DDT, I'll point out the relevant differences between Z80 and 8080 
code in a footnote at the end of the chapter.

     ;1 is the read command
     ;To send this one byte to the APPLE, load it into register C 
and call WRHSTBYTE.
     LD   C,01
     CALL WRHSTBYTE

     Of  course,  if you are using ZSID or DDT,  you type in  the 
address of the subroutine, $FFE3 (see above), not its name.

     ;$FBO9 is the starting address in the APPLE memory.
     ;To  send this one word to the APPLE,  load it into  DE  and 
call WRHSTWORD.
     LD   DE,FB09
     CALL WRHSTWORD

     ;$8  is the number of bytes we are fetching.  Express it  as 
$0008, i.e., a full word.
     LD   DE,0008
     CALL WRHSTWORD

     ;The  APPLE  has  all the parameters it  requires,  but  the 
STARCARD is not yet ready.
     ;$3000 is the starting address in the STARCARD memory  where 
the data will be deposited.
     ;$0008 is the number of bytes (again).
     ;To  set up the STARCARD and then tell the APPLE to send the 
data call RDHSTBYTS.
     LD   HL,3000
     LD   DE,0008
     CALL RDHSTBYTS

     ;That's all there is to it except to return.
     RET

     It  is easy to see from this example how the parameters  are 
set for the different subroutines.

     The program on the disk RDTEST.COM takes this a step further 
and,  after removing bit 7 from each byte, prints the data on the 
screen.

     EXAMPLE 2. Send a sentence to the APPLE text screen.

     ;2 is the write command.
     LD   C,02
     CALL WRHSTBYTE

     ;$428  is the beginning of the ninth line on the APPLE  text 
screen.
     LD   DE,0428
     CALL WRHSTWORD

     ;$E is the length of the message.
     LD   DE,0013
     CALL WRHSTWORD

     ;$011B is the starting address of the message.  I  assembled 
the  program starting at $0100 and the data began at $0111B after 
the final RET.
     ;$E is the number of bytes (again).
     ;To send the message call WRHSTBYTS.
     LD   HL,011B
     LD   DE,0013
     CALL WRHSTBYTS

     RET

     ;Message
     C8 C5 CC CC CF A0 C6 D2 CF CD A0 D3 D4 C1 D2 C3 C1 D2 C4

     You will have to switch to the 40-column text screen to  see 
the result.

     This is program WRTEST.COM on the disk.

     EXAMPLE  3.  Send a routine to the APPLE to beep the speaker 
and then run it.

     ;This  first  part is almost identical to the first part  of 
the last example.
     LD   C,02
     CALL WRHSTBYTE

     LD   DE,0300
     CALL WRHSTWORD

     LD   DE,0006
     CALL WRHSTWORD

     LD   HL,0126
     LD   DE,0006
     CALL WRHSTBYTS

     ;3 is the run command.
     LD   C,03
     CALL WRHSTBYTE

     ;The subroutine starts at $0300 in APPLE memory.
     ;To execute it call WRHSTWORD.
     LD   DE,0300
     CALL WRHSTWORD

     RET

     ;The data is placed immediately after this subroutine.
     A9 87 20 F0 FD 60

     In 6502 assembly language, it is:

     LDA  #$87      ;<control-G>
     JSR  $FDF0     ;Output it.  This is the COUT1 subroutine in 
the APPLE's monitor.
     RET
     
     This is program RUNTEST.COM on the disk.

     With  these programs as models,  all sorts of things  become 
possible! The next example is very much like the last.

     EXAMPLE 4. A cold boot program.

     It  is  often useful to be able to perform a cold boot  from 
inside  CP/M.  You  may want to boot up a DOS  3.3  disk  without 
switching off the power.  With the STARCARD, we first have to get 
out of the STARCARD into the APPLE.  So we transfer a routine  to 
APPLE memory and execute it.

     LD   C,02
     CALL WRHSTBYTE

     LD   DE,0300
     CALL WRHSTWORD

     LD   DE,0008
     CALL WRHSTWORD

     LD   HL,0126
     LD   DE,0008
     CALL WRHSTBYTS

     LD   C,03
     CALL WRHSTBYTE

     LD   DE,0300
     CALL WRHSTWORD

     RET

     ;The data is placed immediately after this subroutine.
     A9 00 8D F4 03 6C FC FF

     In 6502 assembly language, it is:

     LDA  #$00
     STA  $03F4     ;This will ensure a cold boot.
     JMP  ($FFFC)   ;Reset.

     This is program SBOOT.COM (for STARCARD boot) on the disk.

     EXAMPLE 5. Crash into APPLE memory.

     I found it handy, when investigating the STARCARD to be able 
to crash into the APPLE memory to see what was going on there.

     LD   C,02
     CALL WRHSTBYTE

     LD   DE,0300
     CALL WRHSTWORD

     LD   DE,000E
     CALL WRHSTWORD

     LD   HL,0126
     LD   DE,000E
     CALL WRHSTBYTS

     LD   C,03
     CALL WRHSTBYTE

     LD   DE,0300
     CALL WRHSTWORD

     RET

     ;The data is placed immediately after this subroutine.
     A9 69 8D F2 03 A9 FF 8D F3 03 20 6F FB 00

     In 6502 assembly language, it is:

     LDA  #$69
     STA  $03F2
     LDA  #$FF
     STA  $03F3     ;$FF69 is the beginning of the APPLE's 
		    ;monitor subroutine.
     JSR  $FB6F     ;fix up the power-up byte.
     BRK            ;crash.

     This is program SCRASH.COM (for STARCARD crash) on the disk.

     These  programs  will  work only with the  STARCARD.  A  Z80 
SOFTCARD would not understand what was going on.

FOOTNOTES TO CHAPTER 1
----------------------

8080 equivalents
----------------

     LD   C,02      becomes   MVI  C,02
     LD   DE,0300   becomes   LXI  D,0300
     LD   HL,011B   becomes   LXI  H,011B

Other Commands
--------------

     There are some other commands.

     #5 CONNECT a device driver.
	Device drivers look after screen,  keyboard, disk drives, 
printer,  etc. This command is used by DLDRIVER when creating the 
file  DRIVERS,  and  by DRIVERS when a  cold  boot  occurs.  Many 
parameters must be sent. I do not propose to deal with this.

     #6 READ one byte from APPLE memory.
	  LD   C,06
	  CALL WRHSTBYTE
	  LD   DE,nnnn   ;nnnn is the address in APPLE memory.
	  CALL WRHSTWORD ;the byte appears in register A.
	  CALL RDHSTBYTE
	  RET

     This is program C6TEST.COM on the disk.

     #7 WRITE one byte to APPLE memory.
	  LD   C,07
	  CALL WRHSTBYTE
	  LD   DE,mmmm
	  CALL WRHSTWORD
	  LD   C,bb      ;bb byte
	  CALL WRHSTBYTE
	  RET

     This is program C7TEST.COM on the disk.

CHAPTER TWO
-----------
HOW THE APPLE TALKS TO THE STARCARD
-----------------------------------

     The approach is the same.

     1. Send command number to the STARCARD.
     2. Send any parameters that are required.

     The three important commands are similar.

     #1 READ from STARCARD memory
     
     #2 WRITE to STARCARD memory

     #3 RUN a subroutine located in STARCARD memory

     If  you  have booted with DOS 3.3 or some similar  operating 
system,  the STARCARD will need to be reset before these commands 
can be used. This is done by reading or writing to $C0n5,X ,where 
X  is  the  slot no.  of the STARCARD times  16  (e.g.,  If  your 
STARCARD  is  in  slot 4,  then X is  $40.  See  footnote.).  The 
STARCARD should send back a $5A (the letter "Z" in Z80).

     In 6502 code:

107F: 40       SLOTNUM:
			      ;Store slot no.*16 here.      

1080: AE 7F 10 RESET:         LDX  SLOTNUM
1083: BD 85 C0                LDA  $C085,X
				   ;Reset STARCARD.
1086: 20 8E 10 LOOP0:         JSR  RD1Z80BYTE
				   ;Reads   the  byte  returned   (see 
below).
1089: C9 5A                   CMP  #$5A
				   ;Is it "Z"?
108B: D0 F9                   BNE  LOOP0
				   ;If not, read again. 
108D: 60                      RET

     Reading  and writing are done by the routines RD1Z80BYTE and 
WR1Z80BYTE.  These  will  be  present in  the  APPLE  memory,  at 
addresses  $B009  and $B00C respectively,  only if  the  STARCARD 
operating system has been booted.  In general,  they will not  be 
present, so we shall write them into our program.

108E: AE 7F 10 RD1Z80BYTE:    LDX  SLOTNUM 
				   ;Load the slot no.
1091: BD 83 C0 LOOP1:         LDA  $C083,X
1094: 10 FB                   BPL  LOOP1     
				   ;If bit 7 is 0,  there is  no 
byte waiting, so loop.

1096: BD 80 C0                LDA  $C080,X   
				   ;If it is 1, read the byte.
1099: 60                      RTS

109A: A8       WR1Z80BYTE:    TAY             
				   ;Put byte in Y register  for 
safekeeping.
109B: AE 7F 10                LDX  SLOTNUM
109E: BD 82 C0 LOOP2:         LDA  $C082,X   
				   ;If bit 7 is 1,  the STARCARD 
has not read the last byte sent, so loop.
10A1: 30 FB                   BMI  LOOP

10A3: 98                      TYA
10A4: 9D 81 C0                STA  $C081,X   
				   ;If it is  0,  transfer  byte 
back to A and send it.
10A7: 60                      RTS

     We  shall  also  need  a routine for  sending  a  string  of 
characters  to the STARCARD.  I shall follow the pattern and call 
it WR1Z80BYTS.

     The starting address of the command string will be stored at 
$00, $01 (CMDLO, CMDHI) and the length in $02 (CMDLENGTH).

10A8: A0 00    WR1Z80BYTS:    LDY  #$00
				   ;Initialize Y.
10AA: 98       LOOP3:         TYA
10AB: 48                      PHA
				   ;Put    Y   in    stack    for 
safekeeping.     
10AC: B1 00                   LDA  (CMDLO),Y
10AE: 20 9A 10                JSR  WR1Z80BYTE
				   ;Fetch the byte and send it.
10B1: 68                      PLA
10B2: A8                      TAY
10B3: C8                      INY
10B4: C4 02                   CPY CMDLENGTH
10B6: 90 F2                   BCC LOOP3
				   ;Retrieve  Y and see if end  of 
command string has been reached. BCC here serves as a BLT, branch 
if less than, instruction.
10B8: 60                      RTS          


     EXAMPLE 1. Read a message from the STARCARD memory.

     ;Reset the STARCARD.
1000: 20 80 10 START:         JSR  RESET

     ;Set up addresses $00, $01 and $02 with the starting address 
of the command string and its length.
1003: A9 40    SENDCMD:       LDA  CMDLO
1005: 85 00                   STA  $00
1007: A9 10                   LDA  CMDHI
1009: 85 01                   STA  $01
100B: A9 05                   LDA  CMDLENGTH
100D: 85 02                   STA  $02

     ;Send the command string.
100F: 20 A8 10                JSR  WR1Z80BYTS
1012: 60                      RTS

     ;Here  is  the  command string.  As you can  tell  from  the 
SENDCMD subroutine above, it starts at $1040 and is 5 bytes long.
     ;1 is the read command.
1040: 01
     ;The message begins at $FB58 in the STARCARD memory.
1041: 58 FB
     ;The message is $2A bytes long.
1043: 2A 00

     The  code from $107F to $10B8 is the same as that  described 
above.

     The program RDTEST.DOS on the DOS 3.3 side of the disk takes 
this  a step further and displays the message on the  screen.  In 
order  to  see something really interesting to convince  yourself 
that  you  are reading the STARCARD,  I suggest that you  do  the 
following:

     Boot STARCARD CP/M disk.
     Run SCRASH.COM described in the previous chapter.
     Boot DOS 3.3 disk using 6 <control-P>.  (i.e.,  Don't switch 
of the power to reboot.)
     Brun RDTEST.DOS.

     EXAMPLE 2. Send a routine to the STARCARD and execute it.

     I shall send a program plus text to the STARCARD.  When  the 
program  is run,  multiple copies of the text appear in  STARCARD 
memory.

     ;Reset the STARCARD.
1000: 20 80 10 START:         JSR  RESET

     ;The  first command string starts at $1040 and is $25  bytes 
long.
1003: A9 40    SENDCMD1:      LDA  CMDLO1
1005: 85 00                   STA  $00
1007: A9 10                   LDA  CMDHI1
1009: 85 01                   STA  $01
100B: A9 25                   LDA  CMDLENGTH1
100D: 85 02                   STA  $02
100F: 20 A8 10                JSR  WR1Z80BYTS

     ;The  second command string starts at $1070 and is $3  bytes 
long.
1012: A9 70    SENDCMD2:      LDA CMDLO2
1014: 85 00                   STA $00
1016: A9 10                   LDA CMDHI2
1018: 85 01                   STA $01
101A: A9 03                   LDA CMDLENGTH2
101C: 85 02                   STA $02
101E: 20 A8 10                JSR WR1Z80BYTS

1021: 60                      RTS

     ;Here is the first command string.
     ;2 is the write command.
1040: 02
     ;The message is to be placed at $8000 in STARCARD memory.
1041: 00 80
     ;The message is $20 bytes long.
1043: 20 00
     ;The first part is the program. In Z80 assembly language, it 
is:
	       LD   HL,8010
	       LD   DE,8020
	       LD   BC,0080
	       LDIR
	       RET
1045: 21 10 80 11 20 80 01 80 00 ED B0 C9 00 00 00 00 
     ;The second part is the text.
1055: 41 50 50 4C 45 20 49 4E 20 41 4F 4E 54 52 4E 4C

     ;Here is the second command string.
     ;3 is the run command.
1070: 03
     ;The  subroutine  to  be  run starts at  $8000  in  STARCARD 
memory.
1071: 00 80

     The  code from $107F to $10B8 is the same as that  described 
above.

     This  is the program WRTEST.DOS on the DOS 3.3 side  of  the 
disk.

     To see the results, I suggest that you do the following:

     Run COLDBOOT on DOS 3.3 disk.
     Insert a STARCARD CP/M disk with ZSID.COM or DDT.COM on it.
     Press any key, as requested.
     Run ZSID.COM or DDT.COM
     Examine memory from $8000 using the D(isplay) option.

FOOTNOTES TO CHAPTER TWO
------------------------

Other Commands
--------------

     There are some other commands.

     #0 IDENTIFY
	  Asks  STARCARD  for its identifier  string  "Z80",  rom 
version (one byte) and serial number (four bytes). Try the
program IDTEST.DOS on the DOS 3.3 side of the disk.

     #4 WRITE one byte to the STARCARD I/O port.
	  LDA  #$04
	  CALL WR1Z80BYTE
	  LDA  #$nn           ;$nn is I/O port number.
	  CALL WR1Z80BYTE
	  LDA  #$bb           ;$bb is byte being sent.
	  RTS

     #5 READ one byte from STARCARD I/O port.
	  LDA  #$05
	  CALL WR1Z80BYTE
	  LDA  #$nn
	  CALL WR1Z80BYTE
	  CALL RD1X80BYTE
	  RTS                  ;The byte is returned in  register 
A.           
     Different Slot
     --------------

     If your STARCARD is in a different slot, slot 5 for example, 
the programs just described will have to be changed.

     Boot DOS 3.3.
     BLOAD RDTEST.DOS 
     CALL -151
     107F: 50 (Your slot no. times 16)
     BSAVE RDTEST.DOS,A$1000,L$C0
     
     Similarly for WRTEST.DOS.
.pa


CHAPTER THREE
-------------
THE TECHNICAL DETAILS
---------------------

	    APPLE                       STARCARD   
     ---------------------         ---------------------
     !      APPLE ADDRESS!         !I/O PORT           !
     !                   !---------!                   !
     !              $C0n0!<<< 8 <<<!0                  !
     !                   !---------!                   !
     !                   !---------!                   !
     !              $C0n1!>>> 8 >>>!20                 !
     !                   !---------!                   !
     !                   !         !                   !
     !        S     $C0n2!------   !          S        !
     !        T   (bit 7)!     !   !          T        !
     !        A          !     ----!(bit 7)   A        !
     !        T          !         !40        T        ! 
     !        U          !     ----!(bit 0)   U        !
     !        S     $C0n3!     !   !          S        !
     !            (bit 7)!------   !                   !
     !                   !         !                   !
     ---------------------         ---------------------  

Notes: n = 8 + slot no. of STARCARD. e.g., If STARCARD is in slot 
4, then $C0n0 is $C0C0.

     STARCARD  to APPLE:  A byte written at I/O port 0 appears at 
$C0n0.  Bit  0 of I/O port 40 (and bit 7 of $C0n3) is set  to  1. 
This bit is cleared to 0 when the APPLE reads the byte.

     APPLE  to STARCARD:  A byte written to $C0n1 appears at  I/O 
port  20.  Bit 7 of $C0n2 (and bit 7 of I/O port 40) is set to 1. 
This bit is cleared when the STARCARD reads the byte.

     The  STARCARD  routines  which  do this  are  RDHSTBYTE  and 
WRHSTBYTE.  We  used these before.  Now let us look at  these  in 
detail.

     RDHSTBYTE:     IN   A,40
		    RLC       ;Puts  bit 7 from the  status  port 
into the carry flag.
		    JP   NC,RDHSTBYTE
			      ;If this bit is 0, there is no data 
waiting, so go back to the beginning.

		    IN   A,20 ;If it is 1, fetch the byte.
		    RET

     WRHSTBYTE:     IN   A,40
		    RRC       ;Puts  bit  0 from the status  port 
into the carry flag.
		    JP   C,WRHSTBYTE
			      ;If it is 1, the APPLE has not read 
the last byte sent, so go back to the beginning.

		    LD   A,C  ;If it is 0, transfer the byte from 
C to A and send it. Remember we always put the byte in register C 
before calling this subroutine.
		    OUT  0,A
		    RET

     The   APPLE  routines  which  do  this  are  RD1Z80BYTE  and 
WR1Z80BYTE. These were described in chapter two.

     RD1Z80BYTE:    LDX  SLOTNUM   ;Load the slot no.
	   LOOP:    LDA  $C083,X
		    BPL  LOOP      ;If  bit 7 is 0,  there is  no 
byte waiting, so loop.

		    LDA  $C080,X   ;If it is 1, read the byte.
		    RTS

     WR1Z80BYTE:    TAY            ;Put  byte in Y  register  for 
safekeeping.
		    LDX  SLOTNUM
	   LOOP:    LDA  $C082,X   ;If bit 7 is 1,  the  STARCARD 
has not read the last byte sent, so loop.

		    TYA
		    STA  $C081,X   ;If  it is  0,  transfer  byte 
back to A and send it.
		    RTS

FOOTNOTES TO CHAPTER THREE
--------------------------

Other Ports
-----------

     There are other ports not shown in the illustration.

     On the APPLE side:

     $C0n5 RESET
	  Read or write to this address resets the Z80 causing it 
to  start again at address $0000.  The use of RESET was described 
in chapter two.

     $C0n6 INTERRUPT
	  Read or write to this address can interrupt the Z80  if 
the  CTC  (counter-timer circuit - an optional chip that  can  go 
into  the empty socket in the STARCARD) is installed and  set  up 
properly.  Initially  the interrupts are disabled.  This line  is 
connected to channel 3 of the CTC.

     $C0n7 NON-MASKABLE INTERRUPT
	  Read or write to this address interrupts the Z80 (it is 
connected  to  the  Z80's NMI pin) causing it to start  again  at 
address $0066. 

     On the STARCARD side:

     I/O port 60 SHADOW MEMORY CONTROL
	  On  the  STARCARD you can have either ROM or  RAM  from 
$0000 to $7FFF. The ROM is turned on at power up and reset.
	  Write 0 to bit 0 of this port switches to RAM
	  Write 1 to bit 0 of this port switches on ROM

     I/O ports 80,81,82,83 CTC CHANNELS 0,1,2,3


STARCARD NOTES
--------------

FERG BRAND 
MAY 1986 (updated JUNE 1986)

1. TWO Z80 CARDS AT ONCE
------------------------

     Godfrey  Gamble  suggested to me to put my Z80  SOFTCARD  in 
slot 4 and my STARCARD in slot 5. It works! No apparent conflicts 
so far.  If I boot with a SOFTCARD disk,  the STARCARD is ignored 
and vice versa.

2. PRINTER PROBLEMS AND THE STARCARD BOOT PROCESS
-------------------------------------------------

     I have an APPLE II+ with an EPSON APL card in slot 1 driving 
an AMUST80 printer.

     The  Z80 SOFTCARD tests slot 1 to see if there  is  anything 
there,  decides  there  is not,  and ignores any control-P's  for 
printout.  The fix is easy. Either (i) run EPSON.COM, or (ii) use 
DDT to put $31 at $DD2F.

     The  STARCARD also tests slot 1 and comes up with  the  same 
answer as the SOFTCARD - there is nothing there.  The fix is more 
difficult  because with the STARCARD you have two microprocessors 
going at once; not one as with the SOFTCARD. The STARCARD carries 
its  own  64k  on board.The critical memory  location  where  the 
result  of  the test is stored is in the ordinary  APPLE  memory. 
Although this is accesible when the STARCARD is operating,  it is 
too late to change anything. 

     The test is carried out by the SFTVIDEO.DVR part of  DRIVERS  
(DRIVERS   includes,   in  the  version  I   use,   SFTVIDEO.DVR, 
APLFLPY.DVR  and  BUFFER.DVR) which must appear on  any  STARCARD 
boot disk. This is written in 6502 code.

     As I understand it,  what happens is this.  On booting,  the 
STARCARD  system  (which  was created using the file  STARCPM  at 
installation time) loads the DOS, and then loads the DRIVERS into 
the  APPLE's  memory.  It  then  adjusts  all  the  JMP  and  JSR 
instructions  so they point to the right places.  In the  DRIVERS 
file they don't. This is called relocation. The system looks at a 
map  that  is  tacked on the end of each individual part  of  the 
DRIVERS file and fixes up each instruction one by one. The system 
then goes to the initialization subroutine in SFTVIDEO.DVR. Among 
other  things this tests each slot to see if it can identify  the 
card there.  The EPSON APL card fails,  as it does with  SOFTCARD 
CP/M,  because  not  all of the memory on board ,  from $C100  to 
$C1FF,  is readable.  SFTVIDEO.DVR also tests,  just like  PRODOS 
does,  to  see what variety of APPLE you have.  Finally it erases 
all  this initialization code and waits for instructions to  come 
through from the STARCARD.

     So  what I did was go to SFTVIDEO.DVR and find an area  that 
was not being used to write over.  I found the slot test  routine 
and  replaced some code by a JSR to my working area.  Back in  my 
working area I reinstated the code I had just replaced and put in 
instructions  to poke the correct answer about the printer  slot, 
and adjusted the bit map for the relocation procedures. Finally I 
INSTALLed the new SFTVIDEO.DVR.

     How are all the changes made?  Use DDT or its Z80 equivalent 
ZSID. Here are the steps in detail.

     Make   a   STARCARD   disk   with   STARCPM,   DLDRIVER.COM, 
SFTVIDEO.DVR,    APLFLPY.DVR,    BUFFER.DVR,   CONFIGSV.COM   and 
INSTALL.COM on it. This will be your mucking around disk.

     Put  the STARCARD disk with DDT on it in drive A:  and  your 
mucking around disk in drive B:

     Cold boot.

     (From now on I'll just write down what I typed.  I'll use  ; 
to indicate comments.)

     DDT B:SFTVIDEO.DVR<ret>

     ;The  point  in the slot test routine I chose was at  $16E7. 
Remember  that programs start at $0100 using DDT.  Make a JSR  to 
the working area.
     S16E7<ret>
     20<ret>
     70<ret>
     19<ret>
     .<ret>

     ;Put new code in working area.
     S1A70<ret>
     C0<ret>
     01<ret>
     D0<ret>
     02<ret>
     A9<ret>
     05<ret>
     99<ret>
     6D<ret>
     8F<ret>
     60<ret>
     .<ret>

     ;This is just 6502 code.
     C0 01          CPY #$01      ;Are we testing slot 1?
     D0 02          BNE A         ;Branch if no
     A9 05          LDA #$05      ;05 means a good printer card
     99 6D 8F     A:STA $8F6D,Y   ;Store result
     60             RTS

     ;Fix relocation bit map.
     S1DBD<ret>
     82<ret>
     .<ret>

     ;Now get out of DDT.
     <control-C>

     ;Save the new version.

     SAVE 30 B:SFTVIDEO.DVR<ret>

     ;I have put this version on the STARCARD side of the disk as 
SFTVIDEP.DVR

     INSTALL<ret>


3. USING THE ZARDAX SHIFT MODIFICATION
--------------------------------------
     The  STARCARD  shift modification is to join pin 24  of  the 
keyboard  connector  to SW2 of the game i/o connector.  When  the 
shift key is pressed, the STARCARD software recognises this. When 
the  key  is  pressed,  the  contents  of  address  $C063  become 
positive. Shift lock is a bit more complicated though.

     ZARDAX,  the word processor,  has a much nicer  scheme.  The 
shift  key shifts and the control key locks and unlocks.  Can  we 
make the STARCARD use the same hardware? Yes.

     The  ZARDAX  modification  is to remove the  558  integrated 
circuit,  plug  in a special i.c.  socket with a couple of  leads 
attached and put the 558 back on top.  The leads go to pins 3 and 
24  of  the keyboars connector.  When the shift key  is  pressed, 
$C067 goes positive;  when the control key is pressed, $C066 goes 
positive.  (Or perhaps vice-versa if your leads are connected the 
other way around.)

     To  make STARCARD recognise the ZARDAX shift key,  here  are 
the steps. I'll abbreviate the write-up this time.

     ZSID B:SFTVIDEO.DVR

     S052E
     67
     .

     S0595
     67
     .

     <control-C>

     SAVE 30 B:SFTVIDEO.DVR

     INSTALL

     Now  to  make  STARCARD  recognise the  ZARDAX  control  key 
modification. I'm not sure I really like this alteration. It gets 
in the way when I use WORDSTAR with all its control key commands.

     We  cannot use the working area I used before because it  is 
erased   by  the  initialization  routine  cleared  and  the  new 
subroutine must be present all the time.  There is a help  screen 
that  is  used  in some 40-column configurations.  I'm  using  40 
columns so I'll write over it. Not quite so elegant.

     ZSID B:SFTVIDEO.DVR

     ;JSR to working area.
     S501
     20 FB 09 .

     ;Control  key test routine.  If the control key was  pressed 
all  by itself,  change the contents of $0094 from $00 to $FF  or 
vice-versa.
     SAFB
     AD 66 C0       LDA $C066      ;Test control key.
     30 17          BMI A          ;Branch if it was not pressed.
     A9 FF          LDA #$FF       ;A delay in case another  key 
was pressed shortly after control key.
     20 A8 FC       JSR $FCA8
     AD 00 C0       LDA $C000      ;Test for other key.
     30 0D          BMI A          ;Branch if one was pressed.
     AD 94 00       LDA $0094      ;Change contents from $00  to 
$FF or v.v.
     49 FF          EOR #$FF
     8D 94 00       STA $0094
     AD 66 C0     B:LDA $C066      ;Test control key  again,  do 
not continue until it is released.
     10 FB          BPL B
     AD 00 C0     A:LDA $C000      ;Read keyboard again.
     60             RTS            ;Return.
     .

     ;Fix bit map
     S1B80
     09
     .
     S1C41
     10 02
     .

     <control-C>

     SAVE 30 SFTVIDEO.DVR
 
     INSTALL

     Of  course you could make all these software changes at  the 
one time.


STARCARD NOTES #2
-----------------

FERG BRAND
JUNE 1986

RAMDISK DRIVERS
---------------

1. SATURN 128K RAMCARD IN SLOT 0
--------------------------------

     (Correction to this section 12 Feb 87)

     I  put this driver after APLFLPY.DVR in the INSTALLation but 
its  position  is  not  critical.   As  long  as  it  goes  after 
SFTVIDEO.DVR and before BUFFER.DVR.  It converts the ramcard into 
drive G: It has the same capacity as a normal disk.

     If  you  want  to use this driver in another  slot,  slot  5 
say, do the following:

     DDT SAT128K.DVR

     ;Change all code like AD 8B C0 to AD DB C0.  In general, $8B 
will become ($8 + $slot num) * $10 + $B. In particular,

     S144
     D4
     .
	
     S14F
     DB
     .

     S152
     DB
     .

     S167
     DA
     .
     
     S18E
     D0
     .

     S1AD
     D3
     .

     S1B0
     D3
     .

     S1DA
     DA
     .

     <control-C>

     SAVE 3 SAT128K.DVR    

     If  the ramcard is in slot 0,  there could be a  problem  if 
both  the printer buffer driver and the ramdisk driver both  want 
to use bank 1 of the ramcard.  BUFFRAM.DVR should be used instead 
of BUFFER.DVR.

2. DIGITEK 128K RAMCARD IN SLOT 0
---------------------------------

     Same remarks as for SATURN card.

     SAT128K.DVR   configures   the  SATURN  card  as  drive   G: 
DIG128K.DVR configures the DIGITEK card as drive J:  If you  want 
to change these letters, DDT the driver, then

     S106  change from whatever it is to nn,  where nn is 06  for 
G:,  07 for H:  and so on up to 0F for P: You can't use A: to F:, 
these  have  been commandeered by APLFLPY.DVR.  

     (Oh well if you really insist on calling your ramdisk  drive 
C:, try the following:

     DDT APLFLPY.DVR
     S108  change  06 to 02.  This reduces the maximum number  of 
drives this driver can serve from 6 to 2.
     Save this modified version.)

3. BUFFRAM.DVR
--------------

     A test to see if the directory tracks have been  initialized 
in  the  ramcard  is inserted into the language  card  tester  of 
BUFFER.DVR. If the ramcard is being used as a ramdisk, BUFFER.DVR 
is tricked into believing there is no language card.

     If  your ramcard is in some other slot,  you can use  either 
BUFFRAM.DVR or BUFFER.DVR.
     
     This  driver should be the last one installed as it  has  to 
see what ram is left for this purpose.
     
     Of  course,  if you do not want a printer buffer,  judt omit 
BUFFER.DVR or its variants. The printer will still work.

4. MEM32K.DVR
-------------

     This  driver  lets you use $4000-$8000 of APPLE memory  plus 
the  language card as a 32K ramdisk,  drive H:  Do not install  a 
BUFFER.DVR if you use this!

5. MEM16K.DVR
-------------

     For those with a 48K APPLE II+ and no language card. It lets 
you use $4000-$8000 of APPLE memory as a 16K ramdisk, drive I: Do 
not install a BUFFER.DVR if you use this!

STARCARD NOTES #3
-----------------

FERG BRAND
JUNE 1986

RUN YOUR FAVOURITE APPLE MACHINE LANGUAGE PROGRAM FROM STARCARD
---------------------------------------------------------------

     On  the  DOS  3.3 side of this disk is  a  machine  language 
program TWINKLE. Try it. BRUN TWINKLE.

     Here  are a series of steps that will allow it to be  stored 
as a CP/M file and executed as a CP/M program.

     i    Boot DOS,  BLOAD TWINKLE, get into monitor (CALL -151), 
AA71.AA72  will tell you that the starting address is  $7B80  and 
AA60.AA61 will tell you that the length of the program is $0880.
     ii    RUN COLDBOOT and boot STARCARD CP/M.  (Don't turn  off 
the power, we want TWINKLE to remain in memory.)
     iii  DDT RDTEST.COM.  We are going to modify this program to 
read TWINKLE. 
	  L
	  Change LXI D,FB09 to LXI D,7B80
		 LXI D,0008 to LXI D,0880, twice
	  S11A C9, this places a RET at this point.
	  SAVE 1 R1.COM
     iv    R1.  This  fetches TWINKLE,  (it was sitting in  APPLE 
memory) and stores it in STARCARD memory starting at $3000.
     v    DDT RUNTEST.COM. We will modify this program now.
	  L
	  Change LXI D,0300 to LXI D,7B80, twice
		 LXI D,0006    LXI D,0880, twice
	  M  3000  3880  126.   Move  the  code  to  the  end  of 
RUNTEST.COM at $126. 3880 is just 3000 + program length.
     vi    SAVE 4 MUSIC.COM.  A file of $880 + the $26  bytes  of 
RUNTEST requires 4 * 256 bytes of file space. 
     vii  MUSIC   

SBOOT and SCRASH
----------------

     You  can  achieve the same effect as SBOOT by <reset>  R.  R 
must be typed in straight after reset.
     You can achieve the same effect as SCRASH by <reset> M.
     On some computers you will need <ctrl-reset>.

     See the STARCARD manual, page 2.6.

COMMUNICATIONS WITH YAM
-----------------------

     YAM  is  the  public  domain  communications  program   'Yet  
Another Modem'.   I have been using it for some time now with the 
Microsoft  SOFTCARD  in conjunction with an APPLE  COMMUNICATIONS 
CARD in slot 2.

     Of  course  the  original  program will not  work  with  the 
STARCARD  because  it  relies on accessing the  status  and  data 
ports, $C0AE and $C0AF respectively, on the communications card.

     On  the  other  hand,  SFTVIDEO.DVR does  know  there  is  a 
communications  card present,  but that does not help us in  this 
instance. The data port on the communications card can be read or 
written  to by BIOS calls to the PUNCH and the  READER.  However, 
YAM requires its own access to the status port.  It does its  own 
checking before reading or writing.

     I wrote a new file YAMEXTRA.C which I included in the  group 
of files to be compiled (I'm using BDSC) and made some changes to 
YAMSYS.H. All of the other files remained intact.

     YAMEXTRA.C
     ----------
/*Routines  for STARCARD because APPLE 6502 addresses  for  APPLE 
COMMUNICATIONS CARD are not directly accessible.

FERG BRAND 25-Jun-86*/

char calla();

ststat()
{
     calla(0xFFE3,0,0,6,0);    /*Runs WRHSTBYTE with 6,  the read 
command,  in C register*/
     calla(0xFFE9,0,0,0,0xC0AE);    /*Runs  WRHSTWORD with status 
port address in DE register*/
     return(calla(0xFFE0,0,0,0,0));       /*Runs  RDHSTBYTE   and 
returns with the status byte in the A register*/
}

stdatard()
{
     calla(0xFFE3,0,0,6,0);
     calla(0xFFE9,0,0,0,0xC0AF);
     return(calla(0xFFE0,0,0,0,0));     /*Reads the data byte*/
}

stdatawr(data)
char data;
{
     calla(0xFFE3,0,0,7,0);    /*7 is the write command*/ 
     calla(0xFFE9,0,0,0,0xC0AF);
     calla(0xFFE3,0,0,data,0);     /*Runs WRHSTBYTE with the data 
in the C register*/
}

     YAMSYS.H
     --------

     The important changes are:

char ststat(), stdatard();

#define MIMASK 0x01
#define MIREADY (ststat() & MIMASK)
#define MICHAR stdatard()
#define MOMASK 0x02
#define MOREADY (ststat() & MOMASK)
#define MODATA DPORT

#define Sport SPORT
#define Dport DPORT

#define inp(SPORT) ststat()
#define peek(SPORT) ststat()
#define inp(DPORT) stdatard()
#define peek(DPORT) stdatard()
#define outp(DPORT,A) stdatawr(A)

     Most  of the last group are just sort of housekeeping things 
because the same objects sometimes appear differently in the other 
YAM files.

		 
 
