DataMuseum.dkPresents historical artifacts from the history of: CR80 Hard and Floppy Disks |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CR80 Hard and Floppy Disks Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 23090 (0x5a32) Types: TextFile Names: »FDLOAD«
└─⟦af8db8df8⟧ Bits:30005566 8" CR80 Floppy CR80FD_0245 ( CR/D/1242 ) └─⟦ce5288cf7⟧ └─ ⟦this⟧ »FDLOAD«
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 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;