DataMuseum.dk

Presents historical artifacts from the history of:

CR80 Hard and Floppy Disks

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about CR80 Hard and Floppy Disks

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦f8e5108af⟧ TextFile

    Length: 23090 (0x5a32)
    Types: TextFile
    Names: »FDLOAD«

Derivation

└─⟦af8db8df8⟧ Bits:30005566 8" CR80 Floppy CR80FD_0245 ( CR/D/1242 )
    └─⟦ce5288cf7⟧ 
        └─ ⟦this⟧ »FDLOAD« 

TextFile

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE LOAD_BOOT_FILE   I:(MODE_OF_OPERATION)
;                            R(LINK: FAILED, LINK+1 SUCCES);
;                               LOAD OK
; R0    DRIVE_NUMBER            DESTROYED
; R2    TYPE_OF_XFER (-/'X')    PSW CORRESPONDING TO BOOT_FILE
;                                   DEVICE STATUS IF FAILED LOAD;
; R3    -                       BASE OF LOADED FILE
; R6    LINK                    DESTROYED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  FDREAD=     2#00010<11
  FDRESTORE=  2#01000<11
  FDSEEK=     2#00100<11
  FDSELECT=   2#00000<11
  FDWRITE=    2#00001<11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;
FD1000:                             ;LOAD_BOOT_FILE:
        MOV          R6  FD10SV     ;
        XTR          R0  2          ;   ISOLATE DRIVE NUMBER (0_3);
        MOV          R0  FD10DRV    ;
                                    ;
        ADDC -<:O:>             R2  ;   NORMALIZE;
        MOV          R2  FDMODE     ;   SAVE MODE_OF_OPERATION (FD/DMA);
        MOV   DMAADR            R7  ;   GET DMA DEVICE_ADR;
        IEQP         R2  <:X:>-<:O:>;   IF INDIRECT TRANSFER
        MODC &           DMRESET    ;   THEN
        WIO  &       R7         R7  ;     MASTER_CLEAR DMA_DEVICE;
                                    ;
        JMPI         S6  SETPARITY  ;
                                    ;
        MOVC  FDZERO            R5  ;   POINT TOP OF AREA TO BE INIT'D;
        MOVC  0                 R7  ;
        MOVC  FDEND-FDZERO      R3  ;   FOR I:=1 UNTIL END_FD_AREA
FD1010:                             ;   DO
        MOV          R7  0.     X5  ;     CLEAR OFF AREA;
        ADDC  1                 R5  ;
        SOB          R3  FD1010     ;
        MOVC  FDBENTRY          R5  ;   POINT BOOT_ENTRY DESCRIPTOR;
        INC          FDAREASIZE.X5  ;   AREASIZE:= 1 SECTOR
        INC          FDSECTORS. X5  ;   SECTOR_PER_BLOCK:= 1
        INC          FDBLOCKS.  X5  ;   BLOCKS_PER_AREA:=  1
        INC          FDAREA.    X5  ;   1ST_AREA ADDRESS:= 0<8+1
        MOD   XBASE
        MOVC  FDDIRBUF          R4  ;   POINT FD_DIRECTORY BUFFER;
        MOV          R4  FDCLOAD    ;
                                    ;
                                    ;   NOTE R3:=0 (BLOCK 0)
        MOVC  FDSEEK            R2  ;   SET-UP TRACK 0 OF LOAD DRIVE;
        JMPI         S6  FDCONTROL  ;   SEEK_TRACK OF LOAD DRIVE;
        JMPI         S6  FDREADBLOCK;
        JMPI         S6  FDTRANSFER ;   TRANSFER LAST SECTOR (ONLY ONE);
        JMPI         S6  FDCOPY     ;
                         FDENTRYLENGTH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;       LOAD BOOT_FILE              ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        MOVC  0                 R6  ;
        MOV          R6  FD20CTL    ;   RISE 1ST TIME FLAG;
        MOVC  FDDIRBUF          R5  ;   POINT DIRECTORY_ENTRY;
        MOVL  FDLOAD.X5         R01 ;   GET LOAD_ADDRESS, PAGE
        MOVL         R01 FDCLOAD.X6 ;     INITIALIZE
        MOVC  FDENTRYLENGTH-1   R3  ;   FOR I:=1 UNTIL ENTRY_LENGTH
FD1020:                             ;   DO
        ADD   0.     X5         R6  ;     COMPUTE DIR_ENTRY CHECKSUM;
        ADDC  1                 R5  ;
        SOB          R3  FD1020     ;   END SUMMING UP;
        INE          R6  0.     X5  ;   IF DISCREPANCY
        JMP              FDENTRYERROR
                                    ;
        MOVC  FDDIRBUF          R5  ;   POINT BOOT DIRECTORY BUFFER;
FD1040:                             ;   REPEAT
        MOV          R3  FDBLOCKNO  ;     SAVE BLOCKNO
        JMPI         S6  FDREADBLOCK;     GET NEXT BLOCK TO MEM_BUFFER;
        MOV   FDBLOCKNO         R3  ;
        INEP         R3  FDHIBLK.X5 ;     TEST IF LAST AREA (BLOCK)
        ADDC  1                 R3  ;
        JMP              FD1040     ;   UNTIL ALL BLOCKS DONE;
                                    ;
        JMPI         S6  FDTRANSFER ;   LAST_TRANSFER;
        JMPI         S6  FDCOPY     ;   REMEMBER COPYING LAST SECTOR;
                         64         ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  FILE LOADED, VALIDATE CHECKSUM   ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        MOV   XBASE             R1  ;
        SVS                     R4  ;   "OWN" PSW;
        MOV   FDLOAD.X5         R6  ;   GET FILE LOAD ADDRESS (START)
        MOV   FDPAGE.X5         R7  ;   GET CORRESPONDING PAGE;
        IOR          R4         R7  ;   COMPUTE RELEVANT PSW;
        MOV   FDCOUNT.X5        R3  ;   FOR I:=1 UNTIL FILE_LENGTH
        IEQ          R3  0          ;
        JMP              FD1060     ;
        MOVC  0                 R0  ;
        LDS          R7             ;
FD1050:                             ;   DO
        MODN         R1
        ADD   0.     X6         R0  ;     COMPUTE CHECKSUM;
        ADDC  1                 R6  ;
        IEQP         R6  0          ;     IF PAGE BOUNDARY
        ADDC & 1<2              R7  ;     THEN ADJUST (NEGLECT CARRY)
        LDS  &       R7             ;        TO NEXT MEMORY SECTION;
        SOB          R3  FD1050     ;   END COMPUTING CHECK-SUM;
                                    ;
        LDS          R4             ;   RETURN "OWN" MEMORY SECTION;
        INE          R0  FDCHECKSUM.X5; BEWARE CHECKSUM_ERROR;
        JMP              FDCHECKSUMERROR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; FILE CHECKED: OK - GET BASE, PAGE ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FD1060:
        JMPI         S4  OUTSTRING,     <:, START=:>, EOT
        MOV   FDLOAD.X5         R2  ;
        JMPI         S6  OUTHEXA    ;
        JMPI         S4  OUTSTRING,     <:, BASE= :>, EOT
        MOV   FDBASE.X5         R2  ;
        JMPI         S6  OUTHEXA    ;
        MOVL  FDPAGE.X5         R23 ;   GET PAGE, BASE
        SVS                     R7  ;
        IOR          R7         R2  ;   COMPUTE RELEVANT PSW;
        MOV   FD10SV            R6  ;   GET LINK;
        JMP              1.     X6  ;   SUCCESSFULL RETURN;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FDENTRYERROR:
        JMPI         S4  OUTSTRING,     <:, ENTRY:>, EOT
        JMP              FD1080     ;
FDCHECKSUMERROR:
        JMPI         S4  OUTSTRING,     <:, CHECKSUM:>, EOT
FD1080:                             ;
        JMPI         S4  OUTSTRING,     <: ERROR:>, EOT
        JMP              FD1099

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DEVICE ERROR
; R2    DEVICE_STATUS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DMAERROR:                           ;DMA_ERROR:
        JMPI         S4  OUTSTRING,     <:, DMA:>, EOT
        JMP              FD1090     ;
FDDISKERROR:
        JMPI         S4  OUTSTRING,     <:, DISK:>, EOT
FD1090:                             ;ERROR_RETURN
        JMPI         S4  OUTSTRING,     <: ERROR=:>, EOT
        JMPI         S6  OUTHEXA    ;
FD1099: JMPI             FD10SV     ;   RETURN CALLER (FAILED LOAD);
;FF«ff»
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE FD_READ_BLOCK    I:(REF(DIR_ENTRY));
;
; THIS PROCEDURE SUPPORTS THE CR8062 FD CONTROLLER. THE CONTROLLER
; WORKS WITH A 64 WORD BUFFER.
; THE PROCEDURE COPIES ALL BUT THE LAST SECTOR OF A BLOCK TO THE
; DEDICATED OUTPUT AREA VIA ITS MEMORY_BUFFER.
;
; HIERARCHY:
;       FILE/AREA[1:10]/BLOCK[1:-]/SECTOR[1:64]/WORD[1:16]/BIT
; THE RELETION BETWEEN PHYSICAL AND LOGICAL SECTORS ARE:
;   TRACK 0:  2, 4,..., 26, 1, 3,..., 25
;   TRACK 1:  14, 16,..,12,13,15,...,11
;   TRACK 2:  26, 1, 3, ...
;   TRACK3:   11,13,15,...
;   .
;   ... UNTIL TRACK 76
;
; R3    BLOCK_NO                DESTROYED
; R5    REF(DIR_ENTRY)          KEPT
; R6    LINK                    DESTROYED
; R0-2,4,7 -                    DESTROYED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;
FD2000:                             ;FD_READ_BLOCK:
        MOV          R6  FD20SV     ;
        MOV          R5         R6  ;
        MOV   FDBLOCKS.X5       R1  ;   GET BLOCKS_PER_AREA;
        IEQ          R1  0          ;
        JMP          S6  FDENTRYERROR;
                                    ;
        MOVC  FDAREAS           R2  ;
FD2010:                             ;   COMPUTE
        ILT          R3         R1  ;     OFF_SET:=
        JMP              FD2020     ;
        SUB          R1         R3  ;     BLOCK_NO MOD BLOCKS_PER_AREA;
        ADDC  1                 R6  ;     ADJUST AREA_REFERENCE;
        SOB          R2  FD2010     ;
        JMP          S6  FDENTRYERROR;    TOO HIGH BLOCK_NO: ENTRY)ERR;
FD2020:
        MOV   FDSECTORS.X5      R1  ;   GET SECTORS_PER_BLOCK;
        MOV   FDAREA.X6         R0  ;   GET AREA'S START LOG_SECTOR_NO;
        IEQ          R0  -1         ;   IF NOT USED
        JMP          S6  FDENTRYERROR;    THEN ENTRY_ERROR;
        JOZ          R3  FD2060     ;   IF .NOT. 1ST BLOCK IN AREA
        MOV          R0         R2  ;
        XTR          R2  8          ;     ISOLATE LOGICAL_SECTOR_NO;
        SWP                     R0  ;     POSITION TRACK_NO;
FD2030:                             ;     COMPUTE
        ADD          R1         R2  ;       1ST_SEC+BLOCK*SEC'S_PER_BL'K
        SOB          R3  FD2030     ;
FD2040:                             ;     COMPUTE
        ILT          R2  27         ;
        JMP              FD2050     ;
        ADDC  1                 R0  ;        ADJUST TRACK_NUMBER;
        ADDC -26                R2  ;       ADJUST SECTOR_NO
        JMP              FD2040     ;     END ADJUSTING TRACK/SECTOR;
FD2050:                             ;
        SLL          R0  8          ;     POSITION TRACK, ZERO SECTOR;
        IOR          R2         R0  ;     INSERT LOGICAL_SECTOR_NO;
FD2060:                             ;FD_SEEK_TRACK:
                                    ;   R0 - TRACK,/LOGICAL_SECTOR_NO
                                    ;   R1 - SECTORS PER BLOCK
                                    ;   REPEAT
        MOV          R0         R2  ;     TRACK_OFFSET:=
        SRL          R2  7          ;       (TRACK_NO*2
        MOV          R2         R3  ;
        ADD          R2         R3  ;
        ADD          R2         R3  ;                *3)
FD2070: IGEP         R3  26         ;
        ADDC -26                R3  ;                    MOD 26;
        JMP              FD2070     ;
                                    ;
        SRL          R2  1          ;     ISOLATE TRACK_NO;
        MOV   FDTRACK           R6  ;
        IEQ          R2         R6  ;     IF NEW TRACK .NOT. CURRENT
        JMP              FD2080     ;     THEN
        MOV          R2  FDTRACK    ;       ESTABLISH AS CURRENT TRACK;
        JMPI         S6  FDWAITCMDCOMPLETE; COMPLETE PREVIOUS COMMAND;
        MOV   FDTRACK           R2  ;
        ADDC  FDSEEK            R2  ;       ESTABLISH SEEK;
        JMPI         S6  FDCONTROL  ;
                                    ;     END ESTABLISHING NEW TRACK;
FD2080:                             ;     REPEAT
        JMPI         S6  FDTRANSFER ;     GET DATA INTO MOMORY_BUFFER;
        MOV          R0         R2  ;
        XTR          R2  8          ;       ISOLATE LOGICAL_SECTOR_NO;
        ADD          R3         R2  ;       ADJUST FOR TRACK_OFFSET;
                                    ;       PHYSICAL_SECTOR_NO:=
        ADD          R2         R2  ;       ((2*(TRACK_OFFSET_LOG_SECT))
        IGE          R2  53         ;
        ADDC -52                R2  ;         MOD 53;
        IGE          R2  27         ;
        ADDC -27                R2  ;             MOD 27;
        ADDC  FDREAD            R2  ;        SET-UP PROPER READ_COMMAND;
        JMPI         S6  FDCONTROL  ;       CONTROL(READ, SECTOR);
        MOV   FD20CTL           R4  ;       GET 1ST TIME FLAG;
        INEP         R4  0          ;       IF COPY DATA FROM LAST READ
        JMPI &       S6  FDCOPY     ;         THEN DO SO;
                         64         ;
        MOV          R6  FD20CTL    ;
                                    ;NEXT_SEGMENT:
        ADDC -1                 R1  ;
        SGE          R1  1          ;   *   PERFORM OUTHER LOOP_CONTROL
        JMPI             FD20SV     ;   *   IF DONE RETURN CALLER;
                                    ;
        ADDC  256       -26     R0  ;       ADJUST TRACK/SECTOR_NO;
        IBNP         R0  BIT7       ;       CHECK IF NEXT TRACK ;
        ADDC  -256      +27     R0  ;
        JMP              FD2080     ;     UNTIL SEC'S THIS TRACK DONE;
        ADDC  1                 R0  ;     NOTE: START SECTOR 1, NOT 0;
        JMP              FD2060     ;   UNTIL AREA DONE (ALL BLOCKS);
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;FF«ff»
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE FD_TRANSFER      I:(REF(BUFFER));
;       WAIT FOR I/F TO GO READY;
;       TRANSFER DATA FROM I/F BUFFER TO MEMORY;
; R2,4,7 -                      DESTROYED
; R6    LINK                    KEPT
; USING:   XR0(X4), XR2(R2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;
                                    ;FD_WAIT_COMMAND_COMPLETE:
FD3000:                             ;FD_TRANSFER:
        MOV          R6  FD30SV     ;
        MOVC  60                R4  ;
        SOB          R4  LOC        ;   WAIT 60-120 USEC;
                                    ;
        MOV   FDMODE            R7  ;   GET MODE_OF_OPERATION
        IEQ          R7  <:X:>-<:O:>;   IF DIRECT TRANSFER
        JMP              FD3050     ;   THEN
        MOV   FDADR             R7  ;     GET FD DEVICE_ADDRESS;
FD3010:                             ;     REPEAT
        MODC             1<15
        SIO          R2         R7  ;       SENSE(ADDITIONAL_STATUS,DEV)
        IBN          R2  BIT6       ;       TEST DEVICE STILL BUSY;
        JMP              FD3010     ;     UNTIL FORMATTER READY;
                                    ;
        MOVC  FDMEMBUF          R2  ;     POINT DEDICATED MEMORY BUFFER;
        MOVC  64                R4  ;     FOR I:=1 UNTIL BLOCK_SIZE
FD3020:                             ;     DO
        RIO          X2         R7  ;       READ(BUFFER_WORD, DEVICE);
        ADDC  1                 R2  ;
        SOB          R4  FD3020     ;     END_FOR_UNTIL;
                                    ;
        SIO          R2         R7  ;     SENSE(STATUS, DEVICE);
        JMP              FD3060     ;   ELSE
FD3050:                             ;     REPEAT
        JMP          S6  DMA        ;       DMA: SENSE REMOTE FD
              2,#8000+FD,DMSMODE,XR0,DMMEMMODE,DMINPUT
        IBN          X4  BIT6       ;       TEST REMOTE FORMATTER BUSY;
        JMP              FD3050     ;     UNTIL FORMATTER READY
        JMP          S6  DMA        ;     DMA: READ 64 WORDS FROM REM.FD
              128,FD,DMRMODE,FDMEMBUF,DMMEMMODE,DMINPUT
        JMP          S6  DMA        ;       DMA: SENSE REMOTE FD
              2,FD,DMSMODE,XR2,DMMEMMODE,DMINPUT
        MOV          XR2        R2  ;     GET PRESENT STATUS;
FD3060:                             ;   END TRANSFERING SECTOR;
        IBN          R2  BIT0       ;   RESET
        ADDC  #FFFF             R2  ;      BIT0 ONLY;
        IEQ          R2  0          ;   IF TRANSFER COMPLETE
        JMPI             FD30SV     ;   RETURN CALLER AS DONE;
                                    ;   ELSE
        IBZ          R2  BIT7       ;   IF .NOT. DISK_CHANGE.OR.OVERRUN
        JMP              FDDISKERROR;   THEN
        MOVC  FDRESTORE         R2  ;     SET-UP FD_RESTORE:
        JMPI         S6  FDCONTROL  ;       STEP DRIVE OUT 79 TIMES TO
                                    ;       USE TRACK_00 FOR RESYNC;
        MOV          R6  FDTRACK    ;*    FORCE NEW SEEK;
        MOVC  FDRECOUNT         R6  ;
        INC              0.     X6  ;     MAINTAIN RESTORE_COUNT;
        IBZ          X6  BIT4       ;     CONTINUATION ALLOWED
        JMP              FD2060     ;       AS LONG AS BELOW 16;
        MOVC  #FFFF             R2  ;     SET-UP ERROR FLAG
        JMP              FDDISKERROR;   END DISK_ERROR HANDLING;
;FF«ff»
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE FD_MEM_COPY
; R6    LINK                    KEPT
; R7    -                       DESTROYED
;
; USING:   PROCESS_DESCRIPTOR
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                                    ;
FD3100:                             ;FD_COPY:
        SVP                         ;
        SVS                     R2  ;   GET OWN PSW;
                                    ;NOTE HAS TO BE MEM_SECTION 0;
        MOV   XBASE             R4  ;      AND BASE;
        MOVC  FDMEMBUF          R5  ;   POINT FD MEM_BUFFER;
        MOV   FDCPAGE           R3  ;   GET CURRENT OUTPUT PAGE;
        IOR          R2         R3  ;   ESTABLISH NEW PSW THAT SECTION;
        MOV   FDCLOAD           R7  ;   POINT OUTPUT_AREA;
        MVP   0.     X6         R1  ;   FOR I:=1 UNTIL BUFFER_SIZE
FD3120:                             ;   DO
        MOV   0.     X5         R0  ;     GET NEXT WORD
        LDS          R3             ;     SWITCH TO RELEVANT SECTION;
        MODN                    R4
        MOV          R0  0.     X7  ;     INSERT WORD IN OUTPUT_AREA;
        LDS          R2             ;     RETURN OWN PAGE;
        INCD         R5         R7  ;     ADJUST POINTERS;
        IEQ          R7  0          ;     IF PAGE BOUNDARY
        ADDC  1<2               R3  ;       THEN SWITCH PAGE
                                    ;          (NEGLECTING CARRY BIT);
        SOB          R1  FD3120     ;   UNTIL WHOLE BUFFER COPIED;
        MOV          R7  FDCLOAD    ;
        MOV          R3  FDCPAGE    ;
        MOVC  XR0               R7  ;   RE-ESTABLISH
        UNS              7          ;      ALL REGISTERS;
        JMP              1.     X6  ;   RETURN CALLER;
;FF«ff»
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE FD_CONTROL       I:(COMMAND);
; R2    COMMAND<11+TRACK/SECTOR     DESTROYED
; R6    LINK                        KEPT
; R7    -                           DESTROYED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
FD3500:                             ;FD_CONTROL:
        MOV   FD10DRV           R7  ;   GET DRIVE NUMBER;
        SWP                     R7  ;   POSITION IN LEFTMOST BYTE;
        ADD          R7         R2  ;   INSERT DRIVE_NO IN COMMAND;
        MOV   FDMODE            R7  ;
        SNE          R7  <:X:>-<:O:>;   IF DIRECT FD_LOAD
        JMP              FD3580     ;   THEN
        MOV   FDADR             R7  ;   GET DEVICE ADDRESS;
        CIO          R2         R7  ;   CONTROL(DATA, DEVICE);
        JMP                     X6  ;   RETURN CALLER;
FD3580:                             ;   ELSE
        MOV          R6  FD30SV     ;
        MOV          R2  XR2        ;
        JMP          S6  DMA        ;     DMA: CONTROL REMOTE DEVICE
              2,FD,DMCMODE,XR2,DMMEMMODE,DMOUTPUT
        JMPI             FD30SV     ;     RETURN CALLER;
                                    ;   END CONTROLLING FD;
;FF«ff»
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROCEDURE DO_DMA (CNT, REM_ADR,REM_PAGE,LOC_ADR,LOC_PAGE,REQUEST);
; R2    -                       DESTROYED
; RL    LINK                    DESTROYED
; R7    -                       DESTROYED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;  DMA IF CHARACTERISTICS
;;;;;;;;;;;;;;;;;;;;;;;;;;
                         ;
                         ;DMA_STATUS:
  DMRQSNT=    BIT3       ;   REQUEST SENT
  DMNTEOB=    BIT5       ;   NOT_EOB
  DMERRM1=    1<BIT6 OR %;   STOPPED
              1<BIT7 OR %;   REMOTE TIME-OUT
              1<BIT8 OR %;   LOCAL TIME-OUT
              1<BIT9     ;   PARITY ERROR
                         ;DMA_COM'DS:
  DMLDBC=     0<8        ;   LOAD BYTE COUNT
  DMLDAD=     1<8        ;   LOAD ADDRESS
  DMLDPG=     2<8        ;   LOAD PAGE
  DMSNRQ=     3<8        ;   SEND REQUEST
  DMSTART=    5<8        ;   START DMA
  DMSTOP=     6<8        ;   STOP DMA
  DMRESET=    7<8        ;   RESET DMA IF
  DMRMBC=     8<8        ;   LOAD REMOTE BYTE COUNT
  DMRMAD=     9<8        ;   LOAD REMOTE ADDRESS
  DMRMPG=    10<8        ;   LOAD REMOTE PAGE
                         ;
  DMINPUT=    2#01       ;   INPUT REQUEST, TYPE 0
  DMOUTPUT=   2#00       ;   OUTPUT REQUEST, TYPE 0
  DMMEMMODE=  #302       ;   MEMORY MODE: LOWER BYTE, PAGE 0
  DMSMODE=    #2         ;   SENSE IO MODE
  DMCMODE=    #2         ;   CONTROL IO MODE
  DMRMODE=    #6         ;   READ IO MODE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DMA:                                ;DMA:
DMA00:                              ;   REPEAT
        MOV   DMAADR            R7  ;     GET DEVICE ADDRESS;
        MOVC  DMOUTPUT          R2  ;     SET-UP CONTROL
        MODC             DMSNRQ
        WIO          R2         R7  ;     OUTPUT(CMD, CTL, DEVICE);
        MOVC  0                 R2  ;     WAIT
        MOVC  0                 R2  ;        2 USEC;
        RIO          R2         R7  ;     INPUT(STATUS, DEVICE);
        IBZ          R2  DMRQSNT    ;   UNTIL REQUEST
        JMP              DMA00      ;      ACCEPTED;
        MVP   0.     X6         R2  ;   GET COUNT_FIELD;
        MODC             DMRMBC
        WIO          R2         R7  ;   OUTPUT(CMD, COUNT, DEVICE);
        MVP   1.     X6         R2  ;   GET REMOTE_ADR;
        MODC             DMRMAD
        WIO          R2         R7  ;   OUTPUT(CMD, REM_ADR, DEVICE);
        MVP   2.     X6         R2  ;   GET REMOTE_PAGE (MODE);
        MODC             DMRMPG
        WIO          R2         R7  ;   OUTPUT(CMD, REM_PAGE, DEVICE);
        MVP   5.     X6         R2  ;   GET REQUEST_TYPE;
        MODC             DMSNRQ
        WIO          R2         R7  ;   OUTPUT(CMD, SEND_REQUEST, DEVICE);
        MVP   0.     X6         R2  ;   GET COUNT
        MODC             DMLDBC
        WIO          R2         R7  ;   OUTPUT(CMD% COUNT% DEVICE);
        MVP   3.     X6         R2  ;   GET POINTER TO OUTPUT_AREA;
        ADD   XBASE             R2  ;
        MODC             DMLDAD
        WIO          R2         R7  ;   OUTPUT(CMD, LOAD_ADDR, DEVICE);
        MVP   4.     X6         R2  ;   GET LOAD_PAGE;
        MODC             DMLDPG
        WIO          R2         R7  ;   OUTPUT(CMD, LOAD_PAGE, DEVICE);
        MODC             DMSTART
        WIO          R2         R7  ;   OUTPUT(CMD, -, DEVICE);
DMA10:                              ;   REPEAT
        RIO          R2         R7  ;     INPUT(STATUS, DEVICE);
        MOVC  DMERRM1           R7  ;     SET-UP ERROR MASK;
        AND          R2         R7  ;     IF RESULT.>0 THEN
        INE          R7  0          ;     IF RESULT<>0 THEN
        JMP              DMAERR     ;*       DMA_ERROR;
        MOV   DMAADR            R7  ;
        IBN          R2  DMNTEOB    ;   UNTIL STATUS.NOT_EOB
        JMP              DMA10      ;      GOES LOW (EOB);
        MODC             DMSTOP
        WIO          R2         R7  ;   OUTPUT(CMD, -, DEVICE);
        JMP              6.     X6  ;   RETURN CALLER;