.TITLE CUTIL - Cartridge Utility .PSECT CUTIL .IDENT /V01.1/ .SBTTL Description .IF NE 0 Author Peter Miedecke Webster Electronics 17 Malvern St Bayswater, 3153 Victoria, Australia (03)729 - 8444 CUTIL is designed to allow the cartridge tape to be used by interactive commands of a single letter. It is similar in concept to "WUTIL". Modification History. --------------------- 1.00 Nov-82 PBM/ Initial version 1.1 Sep-83 PBM/ Fixed up Soft and Underruns count reporting now report them on all status .ENDC .PAGE .sbttl Symbols and Data .GLOBL NUMASC .MCALL .GTLIN,.PRINT,.TTYOUT,.EXIT,.SETTOP,.SCCA .MCALL .QSET,.TTINR .GLOBL TIME ; LINE: .BLKB 81. ;Input line .EVEN LINSAV: .BLKB 81. ;Saved last line .EVEN status: .blkw 6 ;raw status area xstat: .blkw 3 ;formatted status area eoflag: .word 0 ;end of file flag comand: .word 0 ;saved last command executed bufsiz = 22.*256. ;buffer size, in words ; ;Repeat stack and pointer ; .BLKW 40. CSTACK: ;Address of end of stack ; COMSTK: .WORD CSTACK ; ;Numeric Register Area. ; NRTABL: .BLKW 26. ; PROMPT: .ASCII /*/ <200> ; .MACRO TYPE,TEXT .PRINT #TEMP$ TEMP1$=. .=TEMP$ .ASCIZ @TEXT@ TEMP$=. MESLN$=TEMP$-TEMP0$ .=TEMP1$ .ENDM ; ;TYPEN - Like type, but with no cr-lf ; .MACRO TYPEN,TEXT .PRINT #TEMP$ TEMP1$=. .=TEMP$ .ASCII @TEXT@ <200> TEMP$=. MESLN$=TEMP$-TEMP0$ .=TEMP1$ .ENDM ; ;Error macro ; .MACRO ERROR,TEXT JSR PC,ERRPOS .PRINT #TEMP$ TEMP1$=. .=TEMP$ .ASCIZ @TEXT@ TEMP$=. MESLN$=TEMP$-TEMP0$ .=TEMP1$ JMP GETLIN .ENDM .PAGE ; ;Command Table ; .MACRO CMTBLE CMND A,CMWCNT ;Set Tranfer Count CMND B,CMBOT ;BOT rewind CMnd F,cmfwd ;find next file mark CMND E,CMwfm ;write file mark CMND G,CMCOMP ;Compare Read and Write buffers cmnd L,cmlist ;list the first 40 bytes of the ;read buffer CMND M,CMOVE ;Move data from Read to Write buffer CMND N,CMDSEL ;Select specified drive. CMND P,cmpos ;Position - space forward 1 block cmnd S,cmdst ;get status command CMND R,CMREAD ;Read (with implied seek) cmnd U,cmrset ;reset the controller CMND W,CMWRIT ;Write CMND X,CMEXAM ;Examine Register CMND Y,cmret ;Re-tension Cartridge CMND Z,cmerz ;Erase cartridge ; CMND T,CMTIME ;Delay Specified Time .ENDM ; ;Define Command Macro ; .MACRO CMND,CMLETR,CMROUT .BYTE ''CMLETR .ENDM ; CMCHAR: CMTBLE .BYTE 0 ;Terminate the table .EVEN ; ;Bring Down Routine Addresses ; .MACRO CMND,CMLETR,CMROUT .WORD CMROUT .ENDM ; CMROUT: CMTBLE ; ;Register Definitions ;Used in register examination. e.g. XC1 (X- examine Register C1) ;These registers are described in the D3450 manual. ; .MACRO REGTAB REGDEF C1,c.csr,CS1BIT ;Control and Status 1 REGDEF WC,c.wc,0 ;Word (for tranfer) count REGDEF BA,c.ba,0 ;Address of data(for Read or Write) regdef BX,c.bax,0 ;Extended address REGDEF ST,xstat,xbit ;current status .ENDM ; ;Bring down Register name table ; .MACRO REGDEF,PR1,PR2,PR3 .ASCII /PR1/ .ENDM ; RENAM: REGTAB .WORD 0 ;End Table ; ;Bring down register addresses ; .MACRO REGDEF,PR1,PR2,PR3 .WORD PR2 .ENDM REGADD: REGTAB .PAGE ; ;Bring Down Register Bit description Table ; .MACRO REGDEF,PR1,PR2,PR3 .WORD PR3 .ENDM REGBIT: REGTAB ; ;Define Register Bit Mnemonics ; ; ;Control and Status 1 ; CS1BIT: .byte 0,0,0,0,0,0,0,0 .asciz /rdy/ .asciz /ie/ .byte 0,0 .asciz /exc/ .asciz /par/ .asciz /wle/ .asciz /ned/ .EVEN ;current status xbit: .byte 0 .asciz /noc/ .asciz /nod/ .asciz /wpr/ .asciz /eot/ .asciz /dat/ .asciz /fil/ .asciz /eof/ .byte 0 .asciz /ill/ .asciz /dnf/ .asciz /ser/ .asciz /bot/ .byte 0,0 .asciz /rst/ .EVEN .PAGE ; ;Program Status Word. ; PSTAT: .WORD 0 SPSAVE: .WORD 0 ;Saved Stack Pointer RTYCNT: .WORD 0 ;Retry count AREA: .BLKW 5. ;General work area ; QAREA: .BLKW 7 ;Extra queue element ; TIMSTR: .ASCII /HH:MM:SS/<200> .EVEN ERRCNT: .WORD 0 ;Hard Errors ERRPAS: .WORD 0 ;Errors in pass PASCNT: .WORD 0 ;Pass number .PAGE .PAGE .SBTTL Initialization Code START: MOV SP,SPSAVE ;Save stack pointer .QSET #QAREA,#1 ;Extra queue element CLR PSTAT ;Reset program status TYPE < > TYPE TYPE < > TYPE < **WARNING** This utility is for Engineering Maintenance> TYPE < use only. > TYPE < > ; ;Compute Buffer Sizes and Addresses ; MOV @#50,R1 ;Save first free address MOV @#54,R0 ;RMON start MOV 266(R0),R0 ;USR start TST -(R0) ;1 Word below it .SETTOP ;Ask for it ; ADD #1000,R1 ;Round up start BIC #777,R1 MOV R1,RBUFF ;Read Buffer start ; SUB R1,R0 ;Get available space CLC ROR R0 ;Halve it BIC #777,R0 ;Round ; MOV RBUFF,WBUFF ;Get write buffer address ADD R0,WBUFF ; ASR R0 ;Get buffer size MOV R0,RBSIZ ;And set up MOV R0,WBSIZ ; SWAB R0 DEC R0 ;Minus 1, since we float a bit for ;increased randomnes. MOV R0,BLKFAC ;Compute blocking factor ; .SCCA #AREA,#SCCA ;Trap control-c's BIS #20100,@#44 ;Allow REENT and .TTINR TYPEN MOV RBUFF,R0 JSR PC,TYPNUM TYPE < > TYPEN MOV WBUFF,R0 JSR PC,TYPNUM TYPE < > br getlin ; ;Trap Through 4 Routine ; T4ROUT: BIS #1,2(SP) ;Just return with carry set RTI .PAGE .SBTTL Command Interpreter GETLIN: MOV SPSAVE,SP ;Fix up stack .GTLIN #LINE,#PROMPT ;Get line CMPB #033,LINE ;Options wanted? BNE 1$ ;No JMP abort 1$: CMPB #03,LINE ;CTRL-C? bne 2$ jmp abort ; 2$: MOV #CSTACK,COMSTK ;Reset repeat stack TSTB LINE ;Any input? BNE 10$ ;Yes ; ;No input - repeat last line ; MOV #LINSAV,R0 MOV #LINE,R1 ; 5$: MOVB (R0)+,(R1)+ BNE 5$ ; ;Save line for possible repeats ; 10$: MOV #LINE,R0 MOV #LINSAV,R1 ; 11$: MOVB (R0)+,(R1)+ BNE 11$ ; MOV #LINE,R5 ;Point at start of line CLR R4 ;Clear counter ; 20$: MOVB (R5)+,R0 ;Get next byte BEQ GETLIN ;END - get next line ; CMPB R0,#'A ;Command? BLT 30$ CMPB R0,#'Z BGT 30$ ;No ; ;Command Found - find routine ; MOV #CMCHAR,R1 ;Address command table ; 25$: TSTB (R1) ;End? BEQ 27$ ;Yes - illegal command CMPB (R1),R0 ;Found? BEQ 28$ ;Yes TSTB (R1)+ BR 25$ ; 27$: ERROR ; 28$: SUB #CMCHAR,R1 ;Get command number ASL R1 ;Make word offset ADD #CMROUT,R1 MOV (R1),R1 JSR PC,@R1 ;Execute routine BCC 20$ ;and get next command ERROR ; ;Loop, Number or Numeric Register ; 30$: CMPB #'#,R0 ;Numeric register? BEQ 31$ ;Yes CMPB #'+,R0 ;Increment BEQ 32$ ;Yes CMPB #'-,R0 ;Decrement BEQ 33$ CMPB #'=,R0 ;Set register BEQ 34$ CMPB #'!,R0 ;Display? BEQ 35$ ;Yes CMPB #';,R0 ;Clear Number BEQ 36$ ;Yes ; CMPB #'<,R0 ;Repeat? BEQ 40$ ;Yes CMPB #'>,R0 ;End of loop? BEQ 50$ ; CMPB #'0,R0 ;number? BGT 38$ CMPB #'7,R0 BLT 38$ ; ;Number found. Set in R4 ; ASL R4 ;In octal - Shift up ASL R4 ASL R4 SUB #'0,R0 ;convert number to octal ADD R0,R4 ;add in JMP 20$ ;and get next ; ;Numeric Register is number ; 31$: JSR PC,NRADD ;Get register address BR 39$ ;Rest is default ; ;Increment Register ; 32$: JSR PC,NRADD ;Get address ADD R4,(R1) ;Add number to register BR 39$ ; ;Decrement Register ; 33$: JSR PC,NRADD ; SUB R4,(R1) ;Subtract number BR 39$ ; ;Set Register ; 34$: JSR PC,NRADD MOV R4,(R1) ;Set with number BR 39$ ; ;Display Register ; 35$: JSR PC,NRADD MOV (R1),R4 ;Save as number, for compatiblity MOV R4,R0 JSR PC,TYPNUM TYPE < > BR 390$ ; 36$: CLR R4 ;Clear number JMP 20$ ; ;Illigal symbol ; 38$: CMPB #03,R0 ;Control-C? BNE 381$ JMP getlin ; 381$: ERROR ; 39$: MOV (R1),R4 ;Number is always last register value. ; ;If next value is number, clear current number (in R4) ; 390$: CMPB #'0,(R5) ;Number? BGT 391$ ;No CMPB #'9,(R5) BLT 391$ ;No ; CLR R4 ;Clear current number ; 391$: JMP 20$ ;And get next command ; ;Start of Repeat Loop ; ;Save data on repeat stack ; 40$: MOV COMSTK,R2 ;Point at stack TST R4 ;Infinite? (0) BGT 42$ ;No COM R4 ; 42$: MOV R4,-(R2) ;Number of repeats MOV R5,-(R2) ;Start of sequence CLR R4 MOV R2,COMSTK ;Reset repeat stack JMP 20$ ;And continue with commands ; ;End found of repeat loop ;Recall data off stack ; 50$: TST SCCA ;Any CTRL-C? BEQ 52$ ;No ; 51$: .TTINR ;Suck up any CTRL-C's BCC 51$ ; CLR SCCA ;Yes - reset indicator JMP GETLIN ;And see what user wants ; 52$: MOV COMSTK,R2 ;Get stack pointer CMP #CSTACK,R2 ;Nothing saved? BNE 55$ ;No JMP 20$ ;Nothing saved - just ignore ; 55$: TST 2(R2) ;Infinite repeat? BLT 60$ ;Yes ; DEC 2(R2) ;Finished yet? BNE 60$ ;no ; CMP (R2)+,(R2)+ ;Pop repeat stack MOV R2,COMSTK JMP 20$ ;And continue ; ;Repeat loop ; 60$: MOV (R2),R5 ;Get command pointer CLR R4 ;Clear Numeric value ; JMP 20$ .PAGE .SBTTL Options ; ; ABORT: .EXIT .SBTTL CTRL-C Catcher SCCA: 0 ; SCROUT: CLR SCCA .exit .PAGE .SBTTL Command Routines ;R4 MUST BE ZERO ON EXIT!!!!!!!!! ; ;Set Transfer Count ; CMWCNT: NEG R4 ;Count is always negative MOV R4,@#C.WC ;Put in register CLR R4 RTS PC ;BOT rewind cmbot: clr eoflag ;reset flag mov #,r0 jsr pc,execute jsr pc,wait rts pc ; ;Select Drive ; CMDSEL: mov #,r0 jsr pc,execute jsr pc,wait rts pc .PAGE ;Reset any Errors ; CMRERR: MOV #100000,@#WCS1 ;Reset errors RTS PC ; ;Move data from Read to Write buffer ; CMOVE: MOV RBUFF,R1 MOV WBUFF,R2 MOV #BUFSIZ,R0 ; 10$: MOV (R1)+,(R2)+ SOB R0,10$ RTS PC ; ;Read in a Block, according to what is in registers ; CMREAD: tst eoflag ;end-of-file last time? beq 5$ ;no type <*** EOF ***> clr eoflag ;reset flag jsr pc,cmcrdb ;zero read buffer br 20$ 5$: MOV #cc.rd,R0 ; MOV RBUFF,@#C.ba ;Point at Read buffer TST @#c.wc ;Any count set up? BNE 10$ ;yes ; MOV #-256.,@#c.wc ;1 block is the default ; 10$: JSR PC,EXECUTE ;Start transfer JSR PC,WAIT ;Wait for completion ; 20$: RTS PC ;And return ;List the first 40. bytes of the read buffer cmlist: tst r4 ;any number specified? bne 5$ ;yes use that mov #40.,r4 ;otherwise 40. 5$: mov rbuff,r1 mov #70.,-(sp) ;set up counter 10$: movb (r1)+,r0 ;get byte beq 30$ ;ignore nulls cmpb #' ,r0 ;space or greater ble 20$ ;yes cmpb #11,r0 ;tab? beq 20$ ;yes ok cmpb #15,r0 ;cr? beq 20$ cmpb #12,r0 ;lf? bne 15$ ;no mov #71.,@sp ;reset character count br 20$ 15$: dec @sp ;count it mov r0,-(sp) mov #'^,r0 .ttyout mov (sp)+,r0 add #'@,r0 ;make ascii 20$: .ttyout dec @sp bgt 30$ type < > mov #70.,@sp 30$: sob r4,10$ type < > tst (sp)+ ;fix up stack rts pc ; ;Write a block, according to what is in registers ; CMWRIT: MOV #cc.wrt,R0 ; MOV WBUFF,@#c.ba ;Write buffer ; ;Check whether transfer count register set up. 1 block ;transfer (256. words) if it is not. ; RWCHEK: TST @#c.wc ;Any count tt up? BNE 10$ ;yes ; MOV #-256.,@#c.wc ;1 block is the default ; 10$: JSR PC,EXECUTE ;Start transfer ; JSR PC,WAIT ;Wait for completion RTS PC ;And return ;; ;Clear Read Buffer ; CMCRDB: MOV #BUFSIZ,R0 MOV RBUFF,R1 ; 10$: CLR (R1)+ SOB R0,10$ ; CLR R4 RTS PC ; ;Compare Read and Write Buffers ; CMCOMP: CLR R4 MOV #BUFSIZ,R0 MOV RBUFF,R1 MOV WBUFF,R2 ; 10$: CMP (R1)+,(R2)+ BNE 20$ SOB R0,10$ RTS PC ;Compare Ok ; 20$: CMP -(R1),-(R2) ;Fix up pointers for printout TYPEN MOV R1,R0 JSR PC,TYPNUM ; TYPEN < Write Locn: > MOV R2,R0 JSR PC,TYPNUM ; TYPE < > RTS PC .PAGE ; ;Examine Register ; CMEXAM: MOVB (R5)+,R1 MOVB (R5)+,R0 SWAB R0 BIS R1,R0 CLR R4 JMP REGDIS ;forward to file mark cmfwd: tst eoflag ;end-of-file last time? beq 5$ ;no type <*** EOF ***> clr eoflag ;reset flag jsr pc,cmcrdb ;clear read buffer br 10$ 5$: mov #,r0 jsr pc,execute jsr pc,wait 10$: rts pc ;position tape forward one block cmpos: mov #cc.rd,r0 ;read command clr @#c.wc ;with no data to transfer mov rbuff,@#c.ba jsr pc,execute jmp wait ;write file mark cmwfm: mov #,r0 jsr pc,execute jsr pc,wait rts pc ;re-tension cartridge cmret: mov #,r0 ;retension jsr pc,execute jmp wait ;erase cartridge cmerz: mov #,r0 ;erase jsr pc,execute jmp wait ;force a reset cmrset: clrb @#c.bax+1 ;write to the reset byte rts pc ;read and display status cmdst: jsr pc,gsreg ;get and.. jsr pc,dsreg ; display register ;display status counts dscnt: typen < Soft errs: > mov xstat+2,r0 jsr pc,typdec type < > typen < Underruns: > mov xstat+4,r0 jsr pc,typdec type < > rts pc ;get and display status register dsreg: typen < Status: > mov #"ST,r0 jsr pc,regdis rts pc ;get execption status gsreg: mov @#c.wc,-(sp) ;save word count mov #status,@#c.ba mov #-6,@#c.wc mov #,@#c.csr 10$: bit #cs.rdy,@#c.csr beq 10$ mov (sp)+,@#c.wc ;and restore it mov #status,r1 ;get status block mov r1,r0 jsr pc,ssword mov r0,xstat bit #c0.eof,r0 ;eof set? beq 20$ ;no tst @#c.wc ;transfer finish? bne 20$ ;no - real eof cmp #cc.rd,comand ;read command? bne 20$ ;no - only read has delayed eof mov #-1,eoflag ;flag for next read or read file ;mark 20$: mov #status+4,r0 ;point at first byte of soft error ;count jsr pc,ssword ;format properly mov r0,xstat+2 mov #status+10,r0 ;point at first byte of underrun count jsr pc,ssword mov r0,xstat+4 rts pc .PAGE .SBTTL Subroutines ;format status bytes as word ssword: mov (r0)+,-(sp) ;first byte bic #377,(sp) mov (r0),r0 ;second bic #177400,r0 bis (sp)+,r0 rts pc ; ;ERRPOS - Print out error position ; ERRPOS: MOV R5,R1 ;Get position of error SUB #LINE,R1 JSR PC,BELL ;A bell MOV #' ,R0 ;Get space ; 10$: .TTYOUT SOB R1,10$ ; MOV #'^,R0 ;Point at error .TTYOUT ; TYPE < > RTS PC ; ;BELL - Sound the Bell ; BELL: MOV #07,R0 .TTYOUT RTS PC ; ;Wait for I/O to complete. If error detected, display details ; WAIT: bit #cs.rdy,@#c.csr ;ready? beq wait ;no - wait 30$: CLR R4 BIT #cs.exc,@#c.csr ;Error? BEQ 50$ ;No ; 40$: jsr pc,gsreg ;get status tst eoflag ;eof happen? bne 50$ ;yes JSR PC,ERRPOS ;Give error pointer TYPEn jsr pc,dsreg ;display it jsr pc,dscnt ;and status counts JMP GETLIN ; 50$: CLC RTS PC ; ;TYPNUM - Type out a number ; TYPNUM: MOV R1,-(SP) ;Save register MOV #10,R1 ;in octal JSR PC,NUMASC ;into ASCII ; 10$: MOVB (SP)+,R0 ;get numbers off stack .TTYOUT ;And type out ; SOB R1,10$ ;R1 is count of digits ; MOV (SP)+,R1 ;Restore register RTS PC ; ;Display Decimal Numbers ; TYPDEC: MOV R2,-(SP) ;Save registers MOV R1,-(SP) ; MOV #10.,R1 ;Radix MOV #7.,R2 ;Number of digits ; JSR PC,NUMASC ;Convert number to ASCII ; SUB R1,R2 ;Get number of digits BLE 20$ ;Enough ; 10$: MOV #' ,R0 ;Space .TTYOUT SOB R2,10$ ;Enough leading spaces? ;Yes 20$: MOVB (SP)+,R0 ;Digits in reverse order .TTYOUT SOB R1,20$ ;All out? ;Yes MOV (SP)+,R1 ;Restore registers MOV (SP)+,R2 RTS PC .PAGE ; ;NRADD - Get address of numeric or Device register ; NRADD: MOVB (R5)+,R1 ;Get register i.d. CMPB #'@,R1 ;Device Register? BEQ 50$ ;Yes ; CMPB #'A,R1 ;Numeric Register? BGT 40$ ;No CMPB #'Z,R1 BLT 40$ ; ;Convert Letter to Register Address ; SUB #'A,R1 ASL R1 ;Make word offset ADD #NRTABL,R1 RTS PC ; 40$: ERROR ; ;Find Device Register Address ; 50$: MOVB (R5)+,R1 MOVB (R5)+,R0 SWAB R0 BIS R1,R0 JSR PC,FNDREG MOV (R1),R1 ;Point at Register RTS PC .PAGE ; ;REGDIS - Display Register ; REGDIS: JSR PC,FNDREG ;Get Registers address MOV R0,-(SP) ;Save offset MOV (R1),R0 ;Get contents MOV (R0),R0 ; MOV R0,-(SP) ;Save for Mnemonic display MOV #10,R1 ;Octal Radix JSR PC,NUMASC ;Make octal ; MOV #6,R2 ;Want octal zero filled SUB R1,R2 BLE 30$ ;No filling needed ; MOV #'0,R0 ; 25$: .TTYOUT SOB R2,25$ ; 30$: MOVB (SP)+,R0 .TTYOUT SOB R1,30$ ; MOV #' ,R0 .TTYOUT ; ;Get Bit table address ; MOV (SP)+,R2 ;Get register bits MOV (SP)+,R1 ;Offset ADD #REGBIT,R1 ;Pointer MOV (R1),R1 ;Get bit name addresses BEQ CRLF ;None ; ;Interpret the bits in the register ; BITDES: 40$: ASL R2 ;Shift BCS 50$ ;Bit set BEQ 90$ ;No bits left ; ;Bit not set. F d next text ; 45$: TSTB (R1)+ ;Next description Found? BNE 45$ ;No BR 40$ ;Yes ; ;Bit set .Type out its description (if it exists) ; 50$: TSTB (R1) ;Any description? BEQ 45$ ;No ; 55$: MOVB (R1)+,R0 ;Get character BEQ 58$ ;End of description .TTYOUT BR 55$ ; 58$: MOVB #' ,R0 .TTYOUT ;Space seperator BR 40$ ; ;Decsription of register typed. ; 90$: CRLF: TYPE < > ;A CR-LF RTS PC ; ;FNDREG - Get Address of register. ; ;CALL: R0 2 character register mnemonic ; ;RETURN:R1 Register address ; R0 Table offset ; FNDREG: MOV #RENAM,R1 ;Point at table ; 10$: CMP R0,(R1) ;Match? BEQ 20$ ;Yes ; TST (R1)+ ;End? BNE 10$ ;No - continue ; ERROR ; 20$: SUB #RENAM,R1 ;Get offset MOV R1,R0 ;Save offset ADD #REGADD,R1 ;Point at register address RTS PC .PAGE ; ;RANDOM - Return a two word random number in R0 and R1 ; RNDNUM: .WORD 0,0 ;32 Bits ; RANDOM: MOV R2,-(SP) ;Save regs MOV R3,-(SP) ; MOV RNDNUM,R0 MOV RNDNUM+2,R1 CLR R2 MOV #7,R3 ; 10$: ASL R0 ROL R1 ROL R2 SOB R3,10$ ; ADD RNDNUM,R2 ADC R1 ADD RNDNUM+2,R1 ADC R2 ADD #1057,R0 ADC R1 ADC R2 ADD #47401,R1 ADC R2 ADD #6,R2 ADD R2,R0 ADC R1 MOV R0,RNDNUM MOV R1,RNDNUM+2 ; MOV (SP)+,R3 MOV (SP)+,R2 ; RTS PC .PAGE ; ;DIVISION routine ; ;CALL: R0 Dividend. ; R1 Divisor. ; JSR PC,DIV ; ; R0 Quotient. ; R1 Remainder ; DIV: CLR -(SP) ;Clear counter TST R0 ;Trying to divide into zero? BEQ 40$ ;Yes - return with zero ; 10$: SUB R1,R0 ;Subrtract BLOS 20$ ;Division finished? INC (SP) ;No Increment quotient BR 10$ ;And continue subtract ; 20$: BEQ 30$ ;Any remainder? ;yes ADD R1,R0 ;Make remainder positive BR 40$ ; 30$: INC (SP) ;No remainder - inc quot. ; 40$: MOV R0,R1 ;Remainder in R1 MOV (SP)+,R0 ;And quotient in R0 RTS PC ; ;PRTIME - Print time. ; PRTIME: MOV R5,-(SP) MOV #AREA,R5 MOV #1,(R5) MOV #TIMSTR,2(R5) JSR PC,TIME .PRINT #TIMSTR MOV (SP)+,R5 RTS PC ; ;YESNO - Asks [Y/N]? ; ;RETURN:BEQ YES ; YESNO: TYPEN < [Y/N]?> .GTLINE #LINE CMPB #'Y,LINE RTS PC .PAGE ; ;EXECUTE Initiate disk operation. ; ;CALL: R0 Desired operation ; ;RETURN: Immediate, R0 destroyed ; EXECUTE: mov r0,comand ;save last command swab r0 ;position correctly MOV R0,@#c.csr ;Issue command RTS PC ;And return .PAGE .SBTTL Message areas etc ; ;Read and Write Buffers ; RBUFF: .WORD 0 ;Read Buffer Start Address RBSIZ: .WORD 0 ;Read Buffer size ; WBUFF: .WORD 0 ;Write Buffer Start address WBSIZ: .WORD 0 ;Write Buffer size ; BLKFAC: .WORD 0 ;Blocking Factor ; TEMP0$ = . TEMP$ = . .BLKB MESLN$ .EVEN ; END = . .END START