; Uploaded to simtel-20 by Ralph Hyre (ralphw@c.cs.cmu.edu)
; Sent to Ralph by Chris Peck (chris@bingvaxb.bitnet)
; You will need one of the follwing items to use these drivers:
;	the PCPI OEM package (bucks involved - order from PCPI)
;	the assembled output of the PCPI OEM package assembler.
;	(this will be made available here as soon as I can assemble it)

        .TITLE  "VISTA A800 DEVICE DRIVER"
;******************************
;FILE:  VISTA.A65
;PURP:  DEVICE DRIVER FOR VISTA A800 CONTROLLER
;                 AND 8" DISK DRIVES
;
;
;CHANGES:
;
;         01/16/83 (DJH)
;               COMPATABILITY MODE
;
;         12/31/82 (DJH)
;               ERROR RECOVERY FIXES
;
;         12/12/82 (DJH)
;               CREATED
;*******************************
;
BASEP0  .QUERY  "ENTER BASE OF PAGE 0: "
MODE    .QUERY  "MODE: 0=NORMAL, 1=COMPATABILITY ?"
LENP0   .EQU    4
PAGE0W0 .EQU    BASEP0
PAGE0W1 .EQU    BASEP0+2

        .NOLIST
        .INCLUDE B:DRVREQUS.A65
        .LIST

;EQUATES
TRUE    .EQU    1
FLASE   .EQU    0
SOFTVID .EQU    TRUE
FDSK    .EQU    0       ;DEFAULT FIRST DISK IS A

READC   .EQU    1
WRITEC  .EQU    2

ERRCARD .EQU    1       ;ERROR CODE A800 CARD NOT FOUND
ERRAUTO .EQU    2       ;ERROR FROM SELECT
ERRWR   .EQU    3       ;ERROR FROM WRITE/READ

;       VISTA A800 3.0 ROM EQUATES
;
;PAGE ZERO
;
PZ0     .EQU    02CH
PZ1     .EQU    02DH
PZ2     .EQU    02EH
PZ3     .EQU    035H
PZ4     .EQU    03CH
PZ5     .EQU    048H
;
;CP/M PARAMETER PASSING AREA
;
CPARM   .EQU    03E0H
PTRACK  .EQU    03E0H
PSECT   .EQU    03E1H
PVOL    .EQU    03E2H
POVOL   .EQU    03E3H
PDRV    .EQU    03E4H
PODRV   .EQU    03E5H
PSLOT   .EQU    03E6H
POSLOT  .EQU    03E7H
PBUFL   .EQU    03E8H
PBUFH   .EQU    03E9H
PERROR  .EQU    03EAH
PCMMD   .EQU    03EBH
;
;ROM ENTRY POINTS
;
CAUTO   .EQU    0C8F4H
CRWTS   .EQU    0C8FAH
ROMVERS .EQU    0C900H
        .PAGE   "DRIVER HEADER BLOCK"
BEGDRVR:
        .WORD   0               ;LOAD ADDRESS (0=RELOCATE)
        .WORD   ((ENDDRVR-BEGDRVR)+0FFH) AND 0FF00H     ;LENGTH
        .BYTE   LENP0           ;LENGTH OF PAGE 0 DATA
        .BYTE   0               ;TAG FIELD (RESERVED -0-)
FDISK:  .WORD   FDSK            ;FIRST DISK
MDISK:  .WORD   8               ;MAXIMUM NUMBER OF DRIVES
        .WORD   INIT            ;INITIALIZE
        .WORD   READ            ;READ A SECTOR
        .WORD   WRITE           ;WRITE A SECTOR
        .WORD   OTHER           ;OTHER
        .WORD   POLL            ;POLL
        .WORD   3               ;VERSION NUMBER
        .IF     MODE
NAME:   .BYTE   15,"VISTA A800 1.2C" ;DRIVER NAME
        .ELSE
NAME:   .BYTE   14,"VISTA A800 1.2",0 ;DRIVER NAME
        .ENDC

        ;BUFFER SIZE, CHECK SIZE AND ALLOCATION SIZE
        ;             OF EACH DRIVE DEFINED
        ;
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   64              ;CHECK VECTOR SIZE
        .WORD   72              ;ALLOCATION VECTOR SIZE

;   MODIFIED BY SETSEEK PROGRAM

SEEKRATE: .BYTE 02              ;TRACK TO TRACK SEEK SPEED


        .PAGE   "INITIALIZATION ROUTINE"
;******************************
;ROUTINE: INIT
;PURP:  INITIALIZE ENTRY POINT
;ENTRY: NONE
;EXIT:  IF NO ERRORS THEN
;         CLC
;       ELSE
;         SEC
;USED:  ALL
;******************************

        ;INITIIALIZE
INIT:
        LDA     #0
        STA     CURDISK         ;CLEAR CURRENT POINTER
        STA     VISTAFLG        ;CLEAR CONTROLLER FLAG
        LDY     MDISK
        DEY
$1:     STA     TYPEDISK,Y      ;CLEAR TYPE TABLE
        DEY
        BNE     $1
        JSR     FINDER          ;FIND VISTA CONTROLLER CARD
        JMP     EXIT

FINDER:
        LDY     #7
FLOOP1:
        .IF     SOFTVID
        LDA     TYPECARD,Y
        CMP     #2              ;IS IT A DISK CONTROL?
        BNE     FLOOP2          ;NO TRY NEXT CARD
        .ENDC
        JSR     FOUND           ;CHECK FOR A800
        BCS     FLOOP2          ;NO, TRY NEXT CARD
        RTS                     ;GOOD -- GOT IT

FLOOP2: DEY
        BNE     FLOOP1
        LDA     #ERRCARD
        SEC                     ;NO DISK CARD
        RTS

FOUND:
        BIT     0CFFFH          ;TURN OFF COMMON ROM
        TYA                     ;SAVE SLOT #
        ORA     #0C0H           ;SET UP ADDR HI
        .IF     SOFTVID
        .ELSE
        STA     $A+2
        .ENDC
        STA     SLOTON
        STA     *+5             ;FIXUP TURN ON CMMD
        LDA     0C000H          ;TURN ON COMMON ROM
        .IF     SOFTVID
        .ELSE
        LDX     #7
$A:     LDA     0C000H,X        ;GET TYPE BYTE
        CMP     DISKID,X        ;IS IT A DISK?
        BEQ     $B              ;YES, KEEP GOING
        SEC
        RTS

$B:     DEX                     ;CHECK NEXT ID BYTE
        DEX
        BPL     $A
        .ENDC

; FOUND A DISK
; IS IT AN A800?
;
$0:     LDA     CAUTO
        CMP     #04CH           ;IS IT A JUMP?
        BEQ     $1              ;YES KEEP GOING
        SEC
        RTS

$1:     LDA     CRWTS
        CMP     #04CH           ;IS IT A JUMP
        BEQ     $2              ;YES, KEEP GOING
        SEC
        RTS

$2:     LDA     ROMVERS         ;GET ROM VERSION BYTE
        CMP     #030H           ;IS IT 3.0?
        BEQ     $3              ;YES, THIS IS IT
        CMP     #010H           ;BINARY VERSION?
        BEQ     $3              ;YES, STILL OK
        SEC                     ;BAD ROM VERSION
        RTS

$3:     STY     VISTAFLG        ;SET CARD LOCATED FLAG
        TYA
        ASL     A
        ASL     A
        ASL     A
        ASL     A
        STA     SLOT            ;SAVE SLOT * 16
        CLC
        RTS


        .PAGE   "READ/WRITE I/O ROUTINES"
;******************************
;ROUTINE: READ, WRITE
;PURP:  READ AND/OR WRITE A SECTOR
;ENTRY: A = HIGH BYTE OF PARAMETERS
;       Y = LOW BYTE OF PARAMETERS
;         PARM[OCURDSK] = DRIVE
;         PARM[OCURTRK] = TRACK LOW BYTE
;         PARM[OCURTRK+1] = TRACK HIGH BYTE
;         PARM[OCURSEC] = SECTOR LOW BYTE
;         PARM[OCURSEC+1] = SECTOR HIGH BYTE (CURRENTLY 0)
;         PARM[OCURDMA] = BUFFER ADDRESS LOW BYTE
;         PARM[OCURDMA+1] = BUFFER ADDRESS HIGH BYTE
;EXIT:  IF NO ERRORS THEN
;         CLC
;       ELSE
;         SEC
;USED:  ALL
;******************************


READ:
        LDX     #READC
        JMP     VIO


WRITE:
        LDX     #WRITEC
        JMP     VIO


VIO:
        STY     PAGE0W0         ;SAVE PARAM TABLE ADDR
        STA     PAGE0W0+1
        LDA     VISTAFLG        ;GET CONTROLLER FLAG
        BNE     $1              ;
        LDA     #ERRCARD
        SEC                     ;ERROR - NO CARD
        JMP     EXIT

$1:     JSR     SAVELOCS        ;SAVE PAGE ZERO
        JSR     SETUP           ;FORMAT PARAMS FOR ROM
        BCS     $2              ;EXIT IF ERROR
        JSR     CRWTS           ;GO TO ROM TO DO I/O
        LDA     PERROR          ;GET RETURNED ERROR
        BNE     $2              ;YES, ERROR
        CLC
        JMP     $3

$2:     LDA     #ERRWR          ;INDICATE ERROR
        SEC
$3:     JSR     RESTLOCS        ;RESTORE PAGE ZERO
        JMP     EXIT

        .PAGE   "EXECUTER 'OTHER' COMMAND"
;******************************
;ROUTINE: OTHER
;PURP:  OTHER COMMANDS
;ENTRY: PARAMETERS ARE READ DIRECTLY FROM Z-80
;EXIT:  IF NO ERRORS THEN
;         A = 0
;       ELSE
;         A = ERROR NUMBER
;USED:  ALL
;******************************

        ;OTHER COMMANDS
        ; OTHER PARAMETERS ARE DEPENDENT ON WHICH ENTRY IS CALLED
OTHER:
        CMP     #SNDPRMCMD      ;IS THIS THE SEND PARAMETERS COMMAND
        BNE     CHKFRMT         ;BIF NOT SEND PARMATERS

        ;SEND THE HOST AND DISK PARAMETERS
        ; ENTRY PARAMETERS:
        ;       THE DRIVE NUMBER (1 BYTE)
        ; EXIT PARAMETERS:
        ;       ERROR CODE (1 BYTE)

        JSR     RD1Z80BYTE      ;GET DRIVE #
        STA     CURDISK
        LDA     VISTAFLG        ;IS CARD INSTALLED?
        BNE     $1              ;YES, SKIP
        LDY     #00             ;DEFAULT DISK TYPE DS DD
        JSR     SENDBLK         ;TRANSMIT PARAM BLOCK
        LDA     #ERRCARD
        JMP     EXIT

$1:     JSR     SAVELOCS        ;
        LDA     CURDISK         ;GET DRIVE #
        JSR     SELDSK          ;SELECT DISK DRIVE

        LDA     SLOT
        STA     PSLOT           ;SLOT TO IOB

        JSR     CAUTO           ;PERFORM SENSE
        LDA     PERROR          ;GET RETURN FROM IOB
        BPL     $2              ;NO ERROR, SKIP
        LDY     #00             ;DEFAULT DISK TYPE DS DD
        JSR     SENDBLK         ;TRANSMIT PARAM BLOCK
        LDA     #ERRAUTO
        JSR     RESTLOCS
        JMP     EXIT

$2:     AND     #0F0H           ;MASK OFF DRIVE #
        LDX     CURDISK
        STA     TYPEDISK,X      ;SAVE DISK TYPE FOR LATER
        TAX
        JSR     RESTLOCS
        TXA                     ;CALCULATE DISK TYPE
        LSR     A               ;START 0 SS SD X 0 0 0 0
        LSR     A
        LSR     A               ;FINAL 0 0 0 0 0 SS SD 0
        LSR     A               ;                    (DISKTYPE * 2)
;       LSR     A
;       ASL     A
        TAY
        JSR     SENDBLK         ;SEND THE PARAM BLOCK
        CLC
        JMP     EXIT

SENDBLK:
        LDA     ADRPARMS,Y
        STA     PAGE0W0
        LDA     ADRPARMS+1,Y
        STA     PAGE0W0+1
        LDY     #0
        STY     IDX
$1:     LDA     (PAGE0W0),Y
        JSR     WR1Z80BYTE      ;SEND THE NEXT BYTE
        INC     IDX             ;INCREMENT TO NEXT BYTE
        LDY     IDX
        CPY     #SZPARMS        ;ARE WE DONE ?
        BNE     $1              ;BIF NOT DONE
        RTS

        .PAGE
CHKFRMT:
        CMP     #FRMTCMD        ;FORMAT COMMAND ?
        BNE     CHKNAME         ;BIF NOT

        ;FORMAT A DRIVE
        ; ENTRY PARAMETERS:
        ;       THE DRIVE NUMBER (1 BYTE)
        ; EXIT PARAMETERS:
        ;       ERROR CODE (1 BYTE)
        JSR     RD1Z80BYTE      ;GET DRIVE
        LDA     #0FFH
        SEC                     ;INDICATE AN ERROR (NO FORMTING)
        JMP     EXIT

        ;CHECK FOR SEND NAME COMMAND
CHKNAME:
        CMP     #SNDNAMECMD     ;SEND NAME COMMAND ?
        BNE     CHKOTHR         ; BIF NOT

        ; ENTRY PARAMETERS:
        ;       NONE
        ; EXIT PARAMETERS:
        ;       SEND THE LENGTH OF THE NAME (1 BYTE)
        ;       FOLLOWED BYTE THE NAME (LENGTH NUMBER OF BYTES)
        ;       ERROR CODE (1 BYTE)
        LDA     NAME            ;GET LENGTH
        STA     CNT             ;SAVE AS COUNT
        JSR     WR1Z80BYTE      ;SEND IT TO HOST
        LDA     #1
        STA     IDX

$LP:    LDX     IDX
        LDA     NAME,X          ;GET NEXT CHARACTER
        JSR     WR1Z80BYTE      ;WRITE THE NEXT CHARACTER
        INC     IDX
        DEC     CNT
        BNE     $LP             ;CONTINUE UNTIL ALL BYTES ARE SENT
        CLC
        JMP     EXIT

CHKOTHR:
        SEC
        JMP EXIT

        .PAGE   "POLL ENTRY"
;***********************************
;ROUTINE: POLLENTRY
;PURP:  HANDLE POLLING, THIS ENTRY POINT
;       IS CALLED PERIODICALY WHILE THE APPLE IS
;       WAITING FOR A COMMAND FROM THE Z-80. THIS
;       CODE SHOULD BE VERY SHORT AS THE Z-80 IS
;       IGNORED WHILE THIS CODE IS BEING EXECUTED
;ENTRY: NONE
;EXIT:  NONE
;USED:  ALL
;***********************************

POLL:
        RTS

        .PAGE   "GENERAL PURPOSE SUBROUTINES"
;************************************


EXIT:   BCS     ERRXIT
        LDA     #0              ;NO ERRORS
        RTS

ERRXIT:
        TAY
        BNE     RET             ;IF A <> 0 THEN RETURN
                                ; THE SUBROUTINES ERROR CODE
ERROR:
        LDA     #0FFH
RET:    RTS


SETUP:
        STX     PCMMD           ;COMMAND TO IOB
        LDA     #00
        STA     PERROR          ;CLEAR IOB ERROR
        STA     DENSITY         ;DOUBLE DENSITY DEFAULT

        ;CALCULATE CURDISK
        LDY     #OCURDSK
        LDA     (PAGE0W0),Y     ;GET CURRENT DISK
        JSR     SELDSK          ;SELECT DISK DRIVE

        LDA     SLOT
        STA     PSLO    SLOTNO                  ;SKIP QUERY IF SLOTNO <> 0
        BNE     PRESET

        JSR     SETVECTOR               ;SET UP VECTORS TO SFTVIDEO R/W
MESS:   LDY     #00
$1:     INY
        LDA     MESSAGE,Y               ;GET A LETTER FROM MESSAGE
        JSR     APPLEOUT                ;DISPLAY IT
        CPY     MESSAGE                 ;= LENGTH OF MESSAGE?
        BNE     $1

$2:     LDA     #07                     ;BELL CHAR.
        JSR     APPLEOUT
        JSR     APPLEIN                 ;GET CHARACTER
        CMP     #31H                    ;LESS THAN ASCII "1"?
        BCC     $2                      ;TRY AGAIN
        CMP     #38H                    ;>= ASCII "8"?
        BCS     $2                      ;TRY AGAIN
        PHA                             ;APPLEOUT DOESN'T PRESERVE "A"
        JSR     APPLEOUT                ;DISPLAY CHOICE
        PLA
        SEC
        SBC     #30H                    ;CONVERT ASCII TO BINARY
        STA     SLOTNO                  ;AND SET SLOT #

;SET UP ABSOLUTE SLOT ADDRESSES
PRESET: LDA     SLOTNO          ;GET SLOT NUMBER
        ASL     A
        ASL     A
        ASL     A
        ASL     A               ;*16
        CLC
        ADC     #80H            ;ADD 80H FOR TOTAL SLOT OFFSET
        TAY

        STY     SLTBASE         ;INITIALIZE SLTBASE FOR LATER USE

        STY     C0X0A+1
        STY     C0X0B+1
        STY     C0X0C+1
        STY     C0X0D+1
        STY     C0X0E+1         ;INITIALIZE LOW-ORDER SSD ADDRESS BYTE

        INY
        STY     C0X1A+1
        STY     C0X1B+1
        STY     C0X1C+1
        STY     C0X1D+1
        STY     C0X1E+1         ;INITIALIZE HI-ORDER SSD ADDRESS BYTE

        INY
        STY     C0X2A+1
        STY     C0X2B+1
        STY     C0X2C+1         ;BLOCK TO R/W DURING DIRECTORY INITIALIZATION

;TEST THE FIRST 32 BYTES OF SSD BLOCK #1, PAGE #1 (DIRECTORY!) FOR PRESCENCE
;OF THE RAMDISK ID STRING
        LDA     #00
C0X1A:  STA     0C081H          ;SET HI-BYTE
        LDY     #00
C0X0A:  STY     0C080H          ;AND LO-BYTE TO 0
C0X2A:  LDA     0C082H          ;READ BLOCK 1
        CMP     RAMID,Y         ;LOOP UNTIL 16 BYTES OR TEST FAILS
        BNE     $2              ;TEST FAILED, INITIALIZE DIRECTORY
        INY
        CPY     #32
        BNE     C0X0A           ;FALL THRU IF WE PASSED THE TEST AND RETURN
        JMP     IDONE

$2:     LDA     #0E5H           ;FILL THE FIRST 8 PAGES WITH "E5'S"
        LDX     #00
C0X1B:  STX     0C081H
        LDY     #00
C0X0B:  STY     0C080H
C0X2B:  STA     0C082H
        INY
        BNE     C0X0B
        INX                     ;DONE WITH 256 BYTES, NEXT PAGE ....
        CPX     #08
        BNE     C0X1B

;COPY RAMDISK ID OVER THE FIRST 32 BYTES SO A COLDBOOT WON'T REINITIALIZE
C0X1C:  STY     0C081H          ;Y IS ZERO, STy Steven Hirsch w/ acknowledgement
s to:           *
;*                                                                      *
;*                      Wink (Winthrop Saville)                         *
;*                      Fred Meyer                                      *
;*                      Doug Laing                                      *
;*                      Albert F. Woodhull                              *
;*                                                                      *
;************************************************************************

FALSE   .EQU    0               ;ASSEMBLY TIME FALSE
TRUE    .EQU    NOT FALSE

SIZE144 .EQU    FALSE           ;SET TRUE TO ASSEMBLE FOR 144K SYNETIX CARD!

BASEP0  .QUERY  "ENTER BASE OF PAGE 0: "
LENP0   .EQU    4
PAGE0W0 .EQU    BASEP0
PAGE0W1 .EQU    BASEP0+2

;GET SYSTEM EQUATES
        .NOLIST
        .INCLUDE DRVREQUS.A65
        .LIST

;EQUATES
FDSK            .EQU    0       ;DEFAULT FIRST DISK IS A
;
;PAGE ZERO
;
RWDMA   .EQU    0FEH            ;THIS LOCATION WILL HAVE TO BE SAVED

;
CONDEV  .EQU    19              ;CONSOLE IS DEVICE #19

;HEADER
BEGDRVR:
        .WORD   0               ;LOAD ADDRESS (0=RELOCATE)
        .WORD   ((ENDDRVR-BEGDRVR)+0FFH) AND 0FF00H     ;LENGTH
        .BYTE   LENP0           ;LENGTH OF PAGE 0 DATA
        .BYTE   0               ;TAG FIELD (FOR FUTURE MUST BE ZERO)
FDISK:  .WORD   FDSK            ;FIRST DISK
MDISK:  .WORD   1               ;MAXIMUM NUMBER OF DRIVES
        .WORD   INIT            ;INITIALIZE
        .WORD   READ            ;READ A SECTOR
        .WORD   WRITE           ;WRITE A SECTOR
        .WORD   OTHER           ;OTHER
        .WORD   POLL            ;POLL
        .WORD   6               ;VERSION NUMBER
NAME:   .BYTE   15,"SYNETIX RAMDISK"    ;NAME (MUST BE 15 BYTES PLUS THE
                                        ; LENGTH BYTE)

        ;BUFFER SIZE, CHECK SIZE, AND ALLOCATION SIZE
        .WORD   256             ;HOST BUFFER SIZE
        .WORD   0               ;CHECK VECTOR SIZE
        .WORD   18              ;ALLOCATION VECTOR SIZE

;******************************
;ROUTINE: INIT
;PURP:  INITIALIZE ENTRY POINT
;ENTRY: NONE
;EXIT:  IF NO ERRORS THEN
;         A = 0
;       ELSE
;         A = 0FFH
;USED:  ALL
;******************************

        ;INITIIALIZE
INIT:   LDYORE IT IN BOTH LATCHES...
C0X0C:  STY     0C080H
        LDA     RAMID,Y
C0X2C:  STA     0C082H
        INY
        CPY     #32
        BNE     C0X0C

IDONE:  LDA     #00             ;NO ERRORS
        RTS


;******************************
;ROUTINE: READ / WRITE
;PURP:  READ OR WRITE A SECTOR
;ENTRY: A = HIGH BYTE OF PARAMETERS
;       Y = LOW BYTE OF PARAMETERS
;         PARM[OCURDSK] = DRIVE
;         PARM[OCURTRK] = TRACK LOW BYTE
;         PARM[OCURTRK+1] = TRACK HIGH BYTE
;         PARM[OCURSEC] = SECTOR LOW BYTE
;         PARM[OCURSEC+1] = SECTOR HIGH BYTE (CURRENTLY 0)
;         PARM[OCURDMA] = BUFFER ADDRESS LOW BYTE
;         PARM[OCURDMA+1] = BUFFER ADDRESS HIGH BYTE
;EXIT:  IF NO ERRORS THEN
;         CLC
;       ELSE
;         SEC
;USED:  ALL
;******************************

READ:   LDX     #00             ;CODE FOR READ OPERATION
        STX     RWFLAG          ;SET FLAG
        JMP     RWMAIN

WRITE:  LDX     #01             ;WRITE OPERATION
        STX     RWFLAG          ;SET FLAG

RWMAIN: STY     PAGE0W0
        STA     PAGE0W0+1       ;SAVE PARAMETER BLOCK ADDRESS
        JSR     SAVELOCS        ;SAVE PAGE 0 LOCATIONS
        JSR     SETUP           ;SET UP SSD BLOCK#, PAGE OFFSET, AND DMA
        BCS     RWERR
        LDA     PAGENO          ;GET PAGE OFFSET
        LDY     FLAG16K         ;IS IT IN A 16K BLOCK?
        BNE     RW16K

;64K BLOCK R/W LOOP
C0X1D:  STA     0C081H          ;SET UP HIGH ORDER ADDRESS LATCH
        LDY     #00             ;WE WILL ALWAYS START ON A PAGE BOUNDRY
C0X0D:  STY     0C080H          ;SO SET LOW ORDER LATCH TO ZERO
        JSR     RWCOMM
        INY
        BNE     C0X0D              ;LOOP UNTIL WE TRANSFER 256 BYTES
        CLC
        JMP     RWDONE

;16K BLOCK R/W LOO
