************************************************************
*                                                          *
*  I/O Op Code 6 - SAVE                                    *
*                                                          *
*  This routine will save a memory image file from VDP     *
*  RAM.  It has been completely rewritten to use MKFDR     *
*  to create the file header and use I/O routines that     *
*  will write 512 byte blocks directly from VDP RAM.       *
*                                                          *
*  May 9, 1996 - fixed a bug that caused files greater     *
*                than 1023 bytes in length to repeat the   *
*                first two sectors over and over.          *
*                                                          *
************************************************************

SAVE0  ANDI R12,>FF00
       AI   R12,24

       LDCR @ZERO,4
       MOV  @PABBUF+6,R1     Get # of bytes to write
       LDCR @B02,4           Select RAM bank 4

* Set up the parameters for MKFDR

       CLR  @MKFL3           Level 3 records = 0
       MOVB @ZERO,@MKFRL     Record Length = 0
       MOVB @ZERO,@MKFRPS    Records/sector = 0
       MOVB @B01,@MKFLAG     File Flags (Program file)

       SWPB R1
       MOVB R1,@MKFEOF       End of file Offset
       SWPB R1
       AI   R1,255
       SRL  R1,8
       MOV  R1,@MKFSZ        # of sectors needed

       BL   @MKFDR           Make the FDR

       SLA  R1,1
       MOV  @SAVJTB(R1),R1
       B    *R1

SAVJTB DATA SAVE10
       DATA SAVE1        Error code 1
       DATA SAVE2        Error code 2
       DATA SAVE3        Error code 3
       DATA SAVE4        Error code 4
       DATA SAVE5        Error code 5
       DATA SAVE6        Error code 6
       DATA SAVE7        Error code 7

SAVE1  BL   @DSRERR
       DATA >0100
SAVE2  BL   @DSRERR
       DATA >0200
SAVE3  BL   @DSRERR
       DATA >0300
SAVE4  BL   @DSRERR          to do this, don't you think?
       DATA >0400
SAVE5  BL   @DSRERR
       DATA >0500
SAVE6  BL   @DSRERR
       DATA >0600
SAVE7  BL   @DSRERR
       DATA >0700

************************************************************

SAVE10

* The FDR is on disk with a copy of it in the DFDR buffer.
* All AUs for the file have been allocated.  Now start
* writing the data to disk.

       LDCR @ZERO,4          Select RAM bank 0
       MOV  @PABBUF+6,R1     R1 = # of bytes left to write
       JEQ  SAVERT           Empty file, nothing left to do
       MOV  @PABBUF+2,R11    R11 is our buffer pointer
       LI   R10,DFDR+40
       CLR  R5               Sector within AU

* Let's test to see if we can write out 512 bytes.  Otherwise,
* we will have to read in a 512 byte block and overwrite 256
* bytes of it.
*
* The check goes something like this -
*   1.  Our sector buffer pointer must be at the beginning
*       of the sector buffer
*   2.  We must have at least 2 sectors left in this AU.
*

       MOV  R6,R3
       SRL  R3,8
       SLA  R3,1
       LDCR @B04,4
       MOV  @SAUTBL(R3),R3
       LDCR @B02,4           Select RAM bank 2

SAVE11 MOV  *R10+,R2         Get AU
SAVE12
       LI   R4,SECBUF
       MOV  R2,R7
       MPY  R3,R7
       A    R5,R8
       JNC  SAVE13
       INC  R7
SAVE13 SRL  R8,1
       JNC  SAVE14
       AI   R4,>100
SAVE14 SRL  R7,1
       JNC  SAVE15
       ORI  R8,>8000
SAVE15
       LDCR @ZERO,4
       CI   R4,SECBUF
       JNE  SAVE16
       MOV  R3,R0
       DEC  R0
       C    R0,R5
       JEQ  SAVE16
       CI   R1,512
       JL   SAVE16
       JMP  SAVE30

SAVE16 LI   R0,256
       INC  R5
       BLWP @BANKIT
       DATA SCSIRD
       JNE  SAVERR

       SWPB R11          Set VDP read address
       MOVB R11,@VDPWA
       SWPB R11
       MOVB R11,@VDPWA
       NOP

SAVE17 MOVB @VDPRD,*R4+
       DEC  R1
       JEQ  SAVE18
       DEC  R0
       JNE  SAVE17
SAVE18 BLWP @BANKIT
       DATA SCSIWT
       JNE  SAVERR

       CI   R1,0             See if we're done
       JEQ  SAVERT
       AI   R11,256
SAVE19
       C    R5,R3
       JL   SAVE12

       S    R3,R5
       LDCR @B02,4
       C    R2,*R10
       JEQ  SAVE20
       INC  R2
       JMP  SAVE12

SAVE20 INCT R10
       JMP  SAVE11

**
*
* SAVE30 - use sector I/O to write 512 bytes
*
**
SAVE30 CLR  R0
       MOVB R6,R0            SCSI ID
       ORI  R0,>4000         VDP memory,absolute sector size
       MOV  R0,@>834C
       MOV  R11,@>834E
       MOV  R8,@>8350        32 bit sector number
       MOV  R7,@>8352

       LDCR @ZERO,4
       BLWP @BANKIT
       DATA SCSI20

       AI   R1,-512
       JEQ  SAVERT
       INCT R5
       AI   R11,512
       JMP  SAVE19
SAVERT B    @DSRRT

SAVERR BL   @DSRERR
       DATA >0600            Device error
