;******************************************************************************
;            (C) Copyright 1992-1995, Radius, Inc. and Atari Corp.
; Secret and confidential                                   All rights reserved
;******************************************************************************
; This source code and any compilation or derivative thereof is the joint
; property of Radius, Inc. and Atari Corp.  This code is provided pursuant
; to a Software License Agreement and/or Software Development Contract.  This
; code is the proprietary information of Radius, Inc. and Atari Corp. and is
; confidential in nature.  Its use and dissemination by any party other than
; Atari Corp. are strictly limited by the confidential information provisions
; of the Agreement or Contract referenced above.
;******************************************************************************
; 100 06 Nov 95 JPE     Initial revision.
; 101 10 Jan 96 JPE     Modifications to support parental control.
;******************************************************************************

        .nlist
        .include    'memory.inc'
        .include    'params.inc'
        .include    'offset.inc'
        .list

NVM_COOKIE  .equ    '_NVM'              ; Magic cookie
NVM_JAR     .equ    $2400               ; Location of cookie
NVM_BIOS    .equ    $2404               ; NVM BIOS dispatcher

;------ NVM BIOS opcodes ------------------------------------------------------

NVM_INIT    .equ    0                   ; INITIALIZE opcode
NVM_CREATE  .equ    1                   ; CREATE opcode
NVM_OPEN    .equ    2                   ; OPEN opcode
NVM_CLOSE   .equ    3                   ; CLOSE opcode
NVM_DELETE  .equ    4                   ; DELETE opcode
NVM_READ    .equ    5                   ; READ opcode
NVM_WRITE   .equ    6                   ; WRITE opcode
NVM_FIRST   .equ    7                   ; Search FIRST opcode
NVM_NEXT    .equ    8                   ; Search NEXT opcode
NVM_SEEK    .equ    9                   ; SEEK opcode
NVM_INQUIRE .equ    10                  ; INQUIRE opcode

;------ NVM BIOS error codes --------------------------------------------------

NVM_ENOINIT .equ    -1                  ; Not initialized
NVM_ENOSPC  .equ    -2                  ; Not enough space
NVM_EFILNF  .equ    -3                  ; File not found
NVM_EINVFN  .equ    -4                  ; Invalid function
NVM_ERANGE  .equ    -5                  ; Seek out of range
NVM_ENFILES .equ    -6                  ; Out of file handles
NVM_EIHNDL  .equ    -7                  ; Invalid handle

;==============================================================================
;                               InitNVM
;==============================================================================
;   Performs NVM BIOS initialization and initializes the "file-exists" flags
;   for files 1, 2 and 3. If the Memory Track cartridge is not installed, the
;   nvmPresent flag is cleared to inhibit further NVM access.
;
;   Input:  None
;
;   Output: None
;==============================================================================

InitNVM:
        movem.l d0-d1/a0,-(sp)          ; Save registers

        clr     nvmPresent              ; Clear flag by default
        cmpi.l  #NVM_COOKIE,NVM_JAR     ; Is the cookie present?
        bne.s   InitNVExit              ; No, exit

        move    #1,nvmPresent           ; Set present flag
        bsr     Initialize              ; Initialize NVM BIOS
        btst.l  #31,d0                  ; Error?
        bne.s   InitNVError             ; Yes, trap it

        lea     fileControl,a0          ; Start of control block
        moveq   #3-1,d1                 ; Loop 3 times

InitNVLoop:
        move.l  name(a0),fileName       ; Pointer to file name
        clr     exist(a0)               ; Clear by default

        bsr     Open                    ; Try to open file
        cmpi.l  #NVM_EFILNF,d0          ; Not-found error?
        beq.s   InitNVNext              ; Yes, try next one

        move    #1,exist(a0)            ; Set file-exists flag
        move    d0,handle               ; Save handle
        bsr     Close                   ; Close the file
        btst.l  #31,d0                  ; Error?
        bne.s   InitNVError             ; Yes, trap it

InitNVNext:
        lea     FREC_SIZE(a0),a0        ; Next file record
        dbra    d1,InitNVLoop           ; Loop until done

InitNVExit:
        movem.l (sp)+,d0-d1/a0          ; Restore registers
        rts

InitNVError:
        illegal                         ; Trap error

;==============================================================================
;                               SaveNVM
;==============================================================================
;   Saves a configuration set to an NVM file. The file is created if it does
;   not exist.
;
;   Input:  d0.w = 0-relative file index
;           d1.l = byte count in configuration data set
;           a0   = start of configuration data in DRAM
;
;   Output: None
;==============================================================================

SaveNVM:
        movem.l d0-d1/a0,-(sp)          : Save registers

        move.l  a0,bufPtr               ; Pointer to buffer

        lea     fileControl,a0          ; Start of control block
        mulu    #FREC_SIZE,d0           ; Index by record size
        lea     0(a0,d0),a0             ; Block for this file
        move.l  name(a0),fileName       ; Pointer to file name

        move.l  d1,count                ; Save actual byte count
        addi.l  #$1ff,d1                ; Round up to nearest block
        andi.l  #$fffffe00,d1           ; Number of bytes
        move.l  d1,fileSize             ; File size

        bsr     Open                    ; Try to open file
        btst.l  #31,d0                  ; Error?
        bne.s   TryCreate               ; Yes, try to create it

        move    d0,handle               ; Store handle
        bra.s   WriteNVM                ; No, write the data

TryCreate:
        bsr     Create                  ; Create the file
        btst.l  #31,d0                  ; Error?
        bne.s   SaveNVError             ; Yes, we're hosed

        move    d0,handle               ; Store handle

WriteNVM:
        bsr     Write                   ; Write the data
        btst.l  #31,d0                  ; Error?
        bne.s   SaveNVError             ; Yes, we're hosed

        bsr     Close                   ; Close the file
        btst.l  #31,d0                  ; Error?
        bne.s   SaveNVError             ; Yes, we're hosed

        move    #1,exist(a0)            ; Set file-exists flag
        move    minSex,mSex(a0)         ; Sex control attribute
        move    minViolence,mViol(a0)   ; Violence control attribute

        movem.l (sp)+,d0-d1/a0          ; Restore registers
        rts

SaveNVError:
        illegal                         ; Trap error

;==============================================================================
;                              RestoreNVM
;==============================================================================
;   Restores a configuration set from an NVM file.
;
;   Input:  d0.w = 0-relative file index
;           d1.l = byte count in configuration data set
;           a0   = start of configuration data in DRAM
;
;   Output: None
;==============================================================================

RestoreNVM:
        movem.l d0-d1/a0,-(sp)          : Save registers

        move.l  a0,bufPtr               ; Pointer to buffer

        lea     fileControl,a0          ; Start of control block
        mulu    #FREC_SIZE,d0           ; Index by record size
        lea     0(a0,d0),a0             ; Block for this file
        move.l  name(a0),fileName       ; Pointer to file name
        move.l  d1,count                ; Save actual byte count

        bsr     Open                    ; Try to open file
        btst.l  #31,d0                  ; Error?
        bne.s   RestoreNVError          ; Yes, we're hosed

        move    d0,handle               ; Store handle

        bsr     Read                    ; Read the data
        btst.l  #31,d0                  ; Error?
        bne.s   RestoreNVError          ; Yes, we're hosed

        bsr     Close                   ; Close the file
        btst.l  #31,d0                  ; Error?
        bne.s   RestoreNVError          ; Yes, we're hosed

        movem.l (sp)+,d0-d1/a0          ; Restore registers
        rts

RestoreNVError:
        illegal                         ; Trap error

;******************************************************************************
;                     B I O S   F U N C T I O N S
;******************************************************************************

;==============================================================================
;                              Initialize
;==============================================================================
;   BIOS function 0: Initializes NVM BIOS system, registers application name
;   and location of scatchpad area.
;
;   Input:  None
;
;   Output: d0 = 0
;==============================================================================

Initialize:
        move.l  #NVM_SCRATCH,-(sp)      ; Work area
        pea     appName                 ; Application name
        move    #NVM_INIT,-(sp)         ; INITIALIZE opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     10(sp),sp               ; Balance stack
        rts

;==============================================================================
;                                Create
;==============================================================================
;   BIOS function 1: Creates file with specified file name.
;
;   Input:  None
;
;   Output: d0 = file handle if successful
;           d0 = NVM_ENOINIT if BIOS not initialized
;           d0 = NVM_ENOSPC if space cannot be allocated
;==============================================================================

Create:
        move.l  fileSize,-(sp)          ; File size
        move.l  fileName,-(sp)          ; File name
        move    #NVM_CREATE,-(sp)       ; CREATE opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     10(sp),sp               ; Balance stack
        rts

;==============================================================================
;                                 Open
;==============================================================================
;   BIOS function 2: Opens file with specified file name.
;
;   Input:  None
;
;   Output: d0 = file handle if successful
;           d0 = NVM_EFILNF if file not found
;==============================================================================

Open:
        move.l  fileName,-(sp)          ; File name
        move    #NVM_OPEN,-(sp)         ; OPEN opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     6(sp),sp                ; Balance stack
        rts

;==============================================================================
;                                Close
;==============================================================================
;   BIOS function 3: Closes file with specified file name.
;
;   Input:  None
;
;   Output: d0 = 0 if successful
;           d0 = NVM_EIHNDL if invalid handle
;==============================================================================

Close:
        move    handle,-(sp)            ; Handle
        move    #NVM_CLOSE,-(sp)        ; CLOSE opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     4(sp),sp                ; Balance stack
        rts

;==============================================================================
;                                 Read
;==============================================================================
;   BIOS function 5: Reads data from a file and writes to a buffer.
;
;   Input:  None
;
;   Output: d0 = number of bytes read, if successful
;           d0 = NVM_EIHNDL if invalid handle
;==============================================================================

Read:
        move.l  count,-(sp)             ; Byte count
        move.l  bufPtr,-(sp)            ; Pointer to buffer
        move    handle,-(sp)            ; Handle
        move    #NVM_READ,-(sp)         ; READ opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     12(sp),sp               ; Balance stack
        rts

;==============================================================================
;                                Write
;==============================================================================
;   BIOS function 6: Writes data to a file from a buffer.
;
;   Input:  None
;
;   Output: d0 = number of bytes written, if successful
;           d0 = NVM_EIHNDL if invalid handle
;==============================================================================

Write:
        move.l  count,-(sp)             ; Byte count
        move.l  bufPtr,-(sp)            ; Pointer to buffer
        move    handle,-(sp)            ; Handle
        move    #NVM_WRITE,-(sp)        ; WRITE opcode
        jsr     NVM_BIOS                ; Call dispatcher
        lea     12(sp),sp               ; Balance stack
        rts

;------------------------------------------------------------------------------
;   Declare storage.
;------------------------------------------------------------------------------

fileControl:

; Parameters for file #1

                dc.l    fileName1
fileExist1:     dc.w    $dead
minSex1:        dc.w    $dead
minViolence1:   dc.w    $dead

; Parameters for file #2

                dc.l    fileName2
fileExist2:     dc.w    $dead
minSex2:        dc.w    $dead
minViolence2:   dc.w    $dead

; Parameters for file #3

                dc.l    fileName3
fileExist3:     dc.w    $dead
minSex3:        dc.w    $dead
minViolence3:   dc.w    $dead

appName:        dc.b    'GAMEFILM X.16',0

fileName1:      dc.b    'FILM.1',0
fileName2:      dc.b    'FILM.2',0
fileName3:      dc.b    'FILM.3',0

        .even

        .bss

fileName:       ds.l    1               ; Pointer to file name string
fileSize:       ds.l    1               ; File size in bytes
bufPtr:         ds.l    1
count:          ds.l    1
handle:         ds.w    1

nvmPresent:     ds.w    1

;------------------------------------------------------------------------------
;   Declare externals and globals.
;------------------------------------------------------------------------------

        .extern minSex
        .extern minViolence

        .globl  InitNVM
        .globl  RestoreNVM
        .globl  SaveNVM

        .globl  fileControl
        .globl  fileExist1
        .globl  fileExist2
        .globl  fileExist3
        .globl  nvmPresent
