; $Id: pc11copy.mac 1138 2019-04-26 08:14:56Z mueller $ ; Copyright 2019- by Walter F.J. Mueller ; License disclaimer see License.txt in $RETROBASE directory ; ; Revision History: ; Date Rev Version Comment ; 2019-04-25 1138 1.1 add kw11-l/p stress ; 2019-04-21 1134 1.0 Initial version ; ; copy input to output tape ; ; definitions ---------------------------------------------- ; .include |lib/defs_cpu.mac| .include |lib/defs_kwl.mac| .include |lib/defs_kwp.mac| .include |lib/defs_pc.mac| bsize = 256. ; elasticity ring buffer size kpwait = 997. ; kp wait (in cycles, intentionally prime) cbsize = 250. ; kp-per-kl trace buffer size (for last 5 sec) ; ; vector area ---------------------------------------------- ; .include |lib/vec_cpucatch.mac| .include |lib/vec_devcatch.mac| . = v..ptr ; PC11 pr vector .word vh.ptr .word cp.pr7 . = v..ptp ; PC11 pp vector .word vh.ptp .word cp.pr7 . = v..kwl ; KW11-L vector .word vh.kwl .word cp.ars!cp.pr7 ; use alt-reg-set ! . = v..kwp ; KW11-P vector .word vh.kwp .word cp.ars!cp.pr7 ; use alt-reg-set ! ; ; stack area ----------------------------------------------- ; . = 1000 ; stack (below); code (above) stack: ; ; code area ------------------------------------------------ ; ; all context of the pr-to-pp copy is in 6 registers ; r0 bytes read ; !! visible in wait !! ; r1 bytes written ; r2 bytes in buffer ; r3 eof seen flag ; r4 ring buffer write pointer ; r5 ring buffer read pointer ; ; start/stop area --------------------------------- ; start: br start1 stop: halt ; sucessfull stop reset ; and allow re-start ; ; main program ------------------------------------ ; start1: mov #stack,sp ; setup stack 1$: tst @#pr.csr ; wait reader online bmi 1$ 2$: tst @#pp.csr ; wait punch online bmi 2$ ; mov #buf,r4 ; setup wptr mov #buf,r5 ; setup rptr clr r2 ; clear cnt clr r3 ; clear eof clr r0 ; clear rcnt clr r1 ; clear wcnt ; clr klcnt clr kpcnt mov #cbuf,cbptr ; spl 7 mov #kl.ie,@#kl.csr ; start kw11-l mov #kpwait,@#kp.csb ; load kw11-p counter mov #,@#kp.csr ; kw11-p: ext down repeat mov #,@#pr.csr ; start reader spl 0 ; allow interrupts 3$: wait ; and idle br 3$ ; ; reader interrupt handler ------------------------ ; vh.ptr: tst @#pr.csr ; at eof ? bmi 100$ ; if mi yes, stop reader tstb @#pr.csr ; done ? bpl rerr ; if pl no, error halt movb @#pr.buf,(r4)+ ; write char to buffer inc r0 ; inc rcnt cmp r4,#bufe ; wrap ? blo 1$ mov #buf,r4 1$: tst r2 ; test buffer count bne 2$ ; was buffer empty ? bis #pp.ie,@#pp.csr ; then start punch 2$: inc r2 ; inc cnt cmp r2,# ; still space in buffer ? bge 200$ ; no: stop reader inc @#pr.csr ; yes: else request next rti 100$: inc r3 ; set eof flag tst r2 ; any chars pending ? beq 300$ ; if eq not, all done rti 200$: bic #pr.ie,@#pr.csr ; stop reader rti 300$: jmp stop rerr: halt ; reader error halt br rerr ; ; puncher interrupt handler ----------------------- ; vh.ptp: tst @#pp.csr ; punch error bmi perr ; if mi yes, error halt tstb @#pp.csr ; ready ? bpl perr ; if pl no, error halt tst r2 ; test buffer count beq 100$ ; if eq suspend or stop movb (r5)+,@#pp.buf ; and punch next char inc r1 ; inc wcnt cmp r5,#bufe ; wrap ? blo 1$ mov #buf,r5 1$: dec r2 ; dec cnt bit #pr.ie,@#pr.csr ; reader active ? bne 2$ ; mov #,@#pr.csr ; if not, start reader 2$: rti 100$: bic #pp.ie,@#pp.csr ; stop punch tstb r3 ; eof seen ? bne 200$ ; if yes, all done rti 200$: jmp stop perr: halt ; puncher error halt br perr ; ; kw11-l interrupt handler ------------------------ ; checks that ; 1. kl.mon is set (to detect spurious interrupts) ; 2. that kp is tricking ; vh.kwl: tstb @#kl.csr ; done, moni set ? bpl klerr mov #kl.ie,@#kl.csr ; clear moni ; tst klcnt ; no kp check on first kl beq 1$ tst kpcnt ; kwp ticking ? beq kpold ; if not halt ; 1$: mov cbptr,r0 ; log kpcnt to trace buffer mov kpcnt,(r0)+ cmp r0,#cbufe blo 2$ mov #cbuf,r0 2$: mov r0,cbptr clr kpcnt ; and finally clear ; inc klcnt ; inc kl counter, prevent wrap bne 900$ dec klcnt 900$: rti ; klerr: halt kpold: halt ; ; kw11-p interrupt handler ------------------------ ; checks that ; 1. kp.mon is set (to detect spurious interrupts) ; 2. that kl is tricking (if kl stops, kpcnt saturates) ; vh.kwp: tstb @#kp.csr ; done, moni set ? bpl kperr ; inc kpcnt ; inc kp counter, prevent wrap beq klold ; if not also err halt rti ; kperr: halt klold: halt ; ; data area ------------------------------------------------ ; buf: .blkb bsize bufe: ; klcnt: .word 0 kpcnt: .word 0 ; cbptr: .word cbuf cbuf: .blkw cbsize cbufe: .end start