; D0Asm.Asm -- Midas/D0 resident interface procedures ; Last edited: 1 March 1982 .get "masmcommon.d" .get "d0regmem.d" ; OS .bext Zero ; MCMD .bext ErrorAbort ; MDATA .bext BadAText,MDATAtab,MADDRtab,MCTimeOut ; MASM .bextz OddParity,MSave2,MCount ; D0TABLES .bextz NMEMS,MEMLEN ; D0I0 .bext DVx,MIMtab ; Defined here .bext GFrameX,CertifyAV,ConvertAV .bext recvbyte,recvword,sendbyte,sendword .bext ReadPrinter,WritePrinter,d0recvbyte,d0recvword,d0sendbyte,d0sendword .bext stReadOnly,stPassive,stUndAdr,stNotIMA,stNotInVM,stRunning .bextz MADDRH,MADDRL,utilout,utilin .txtm B .zrel MADDRL: 0 MADDRH: 0 utilout: 177016 utilin: 177030 .srel GFrameX: .GFrameX CertifyAV: .CertifyAV ConvertAV: .ConvertAV recvbyte: .recvbyte recvword: .recvword sendbyte: .sendbyte sendword: .sendword ReadPrinter: .ReadPrinter WritePrinter: .WritePrinter d0recvbyte: .d0recvbyte d0recvword: .d0recvword d0sendbyte: .d0sendbyte d0sendword: .d0sendword stReadOnly: .stReadOnly stPassive: .stPassive stUndAdr: .stUndAdr stNotIMA: .stNotIMA stNotInVM: .stNotInVM stRunning: .stRunning .nrel .stReadOnly: .txt "Read-only" .stPassive: .txt "Illegal to write while Passive" .stUndAdr: .txt "Undefined address" .stNotIMA: .txt "??Not IM address??" .stNotInVM: .txt "??Not in VM??" .stRunning: .txt "Illegal to write while running" ; Subroutine using new GetFrame instruction--replaces GetFrame procedure .GFrameX: GtFrame 77400 ; CallSwat() if stack overflow ; **Beginning of code for CertifyAV** ; Special kludge to default address eq memory length to a reasonable value. ; Have 1/ Length and 0/ AddrVec!1 CertX: sub# 1 0 szr jmp CertBad ; Error if address # memory length jsr CertX1 jmp CertBad ; IM jmp CertBad ; IMX jmp CertBad ; RM jmp CnvTask ; T jmp CnvTask ; TPC jmp CertBad ; VM jmp CertBad ; MAP jmp CertBad ; BP jmp CertBad ; MIM jmp CertBad ; MDATA jmp CertBad ; MADDR CertX1: lda 0 5 2 add 0 3 jmp 0 3 ; T 20 and TPC 20 = T(CTASK) and TPC(CTASK). CnvTask: lda 3 @lvDVx lda 0 7 3 ; Offset of CTASK cycle 4 lda 1 cav17 and 1 0 sta 0 MADDRL ; MADDRL = CTASK jmp CertOK lvDVx: DVx cav17: 17 ; CertifyAV(AVec,MemX) returns true if AVec is a legal address in MemX, ; else false .CertifyAV: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs lda 1 5 2 ; MemX lda 3 NMEMS subl# 1 3 szc ; skip if legal MemX 77400 ; else CallSwat lda 3 4 2 ; AVec lda 0 1 3 sta 0 MADDRL ; MADDRL = AVec!1 lda 0 0 3 sta 0 MADDRH ; MADDRH = AVec!0 lda 3 MEMLEN add 1 3 add 1 3 lda 1 0 3 ; MEMLEN!(MemX+MemX) sub# 1 0 szr ; Skip if high parts equal jmp Cert1 lda 1 1 3 ; MEMLEN!(MemX+MemX+1) lda 0 MADDRL Cert1: adcz# 0 1 snc ; Skip if Usc(Addr,Length) < 0 jmp CertX ; Check address eq length kludges CertOK: mkminusone 0 0 skp CertBad: mkzero 0 0 jsr @Return ; Subroutine to check for valid AVec passed to GetMemData and PutMemData ; ConvertAV(AVec,MemX) returns MemX if address is ok, else -1 .ConvertAV: sta 3 1 2 ; Save return jsr @GetFrame 10 jsr @StArgs lda 0 4 2 ; AVec lda 1 5 2 ; MemX jsr .CertifyAV 2 mov# 0 0 snr jmp ConM1 lda 1 5 2 ; MemX jsr CAV1 ConIM-. ConIMX-. ConRM-. ConT-. ConTPC-. ConVM-. ConMAP-. ConBP-. ConMIM-. ConMDATA-. ConMADDR-. CAV1: add 1 3 lda 1 0 3 ; Self-relative pointer add 1 3 lda 0 MADDRL mov 0 1 jmp 0 3 ; Dispatch to setup routine lvMDATAtab: MDATAtab lvMADDRtab: MADDRtab lvMIMtab: MIMtab ConMIM: ; MIMtab+3*address lda 3 @lvMIMtab jmp .+2 ConMDATA: ; MDATAtab+3*address lda 3 @lvMDATAtab add 1 1 skp ConMADDR: ; MADDRtab+2*address lda 3 @lvMADDRtab add 3 0 add 1 0 sta 0 MADDRL ConIMX: ConIM: ConRM: ConT: ConTPC: ConBP: ConVM: ConMAP: ConXit: lda 0 5 2 jsr @Return ; Unimplemented jsr ConUI1 .txt "Unimplemented memory" ConM1: lda 3 @lvBadAText ConUI1: mov 3 0 jsrii lvErrorAbort 1 77400 ; Swat lvBadAText: BadAText lvErrorAbort: ErrorAbort .recvword: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs jsr .recvbyte 0 sta 0 4 2 jsr .recvbyte 0 lda 1 rw377 and 1 0 lda 3 4 2 ands 3 1 add 1 0 jsr @Return rw377: 377 .recvbyte: inc 3 3 sta 3 1 2 ; Save return lda 0 cn1400 ; output off, select PO[4:7] sta 0 @utilout lda 3 cm100 lda 1 c10000 ; look for PO[07] rclp1: lda 0 @utilin and# 0 1 snr jmp lp1end ; PO[07] is low - D0 is sending inc 3 3 szr jmp rclp1 ; D0 not sending--not an error since recvbyte is called while the D0 ; is running, to see if it stopped. lda 0 c252 jmp @1 2 lp1end: lda 0 cn3400 ; select PD[4:7] sta 0 @utilout lda 0 @utilin lda 3 c170000 and 3 0 cycle 4 lda 1 cn2400 ; select PD[0:3] sta 1 @utilout lda 1 @utilin ; read it ands 3 1 add 1 0 sta 0 2 2 ; save complete byte lda 0 cn540 ; send write ack with boot bit high sta 0 @utilout lda 1 cn40540 sta 1 @utilout sta 0 @utilout lda 0 cn1540 ; look for PO[4:7] sta 0 @utilout lda 3 cm100 lda 1 c10000 rclp2: lda 0 @utilin and# 0 1 szr jmp lp2end ; PO[7] is high - D0 has stopped sending inc 3 3 szr jmp rclp2 lda 3 @lvMCTimeOut ; D0 is hung up sending isz 0 3 ; Count failures in COMM-ER0 word 0 jmp @1 2 jmp @1 2 lp2end: lda 0 cn440 ; Drop write ack - D0 should go about its business sta 0 @utilout lda 1 cn40440 sta 1 @utilout sta 0 @utilout lda 0 2 2 jmp @1 2 .sendword: sta 3 2 2 sta 0 pwd movs 0 0 jsr .sendbyte 1 lda 0 pwd lda 3 2 2 .sendbyte: sta 3 1 2 lda 1 cn1440 ; look for PO[4:7] - output off sta 1 @utilout lda 1 c377 and 1 0 ; mask out high bits com 0 0 sta 0 pbyte lda 3 cm100 lda 1 c10000 xlp0: lda 0 @utilin and# 0 1 szr jmp d0rdy inc 3 3 szr jmp xlp0 lda 3 @lvMCTimeOut ; D0 is hung up sending isz 1 3 ; Count failures in COMM-ER0 2nd word jmp .+1 d0rdy: lda 0 pbyte ; strobe byte into PD register sta 0 @utilout movzl 0 1 movzr 1 1 sta 1 @utilout sta 0 @utilout lda 0 cn240 ; set mux to look at PD[0:3] and set strobe into PD register sta 0 @utilout lda 1 cn40240 sta 1 @utilout sta 0 @utilout lda 3 cm100 xlp1: lda 0 @utilin movl 0 0 szc jmp endxlp1 ; PD[00] was 1 - D0 claims it got the data inc 3 3 szr jmp xlp1 lda 3 @lvMCTimeOut ; D0 never responded isz 2 3 ; Count failures in COMM-ER1 1st word jmp .+1 endxlp1: lda 0 cn40 ; drop strobe sta 0 @utilout lda 0 cn40040 sta 0 @utilout lda 0 cn440 ; open bus sta 0 @utilout lda 3 cm100 ; wait for D0 to drop ack xlp2: lda 0 @utilin movl 0 0 snc jmp xret inc 3 3 szr jmp xlp2 lda 3 @lvMCTimeOut ; D0 never removed ack isz 3 3 ; Count failures in COMM-ER1 2nd word jmp .+1 xret: lda 3 1 2 jmp 1 3 lvMCTimeOut: MCTimeOut cn1400: 176377 cm100: 177600 c10000: 10000 c252: 252 cn2400: 175377 c170000: 170000 cn3400: 174377 cn540: 177237 cn40540: 137237 cn1540: 176237 cn440: 177337 cn40440: 137337 pbyte: 0 cn1440: 176337 cn240: 177537 cn40240: 137537 cn40: 177737 cn40040: 137737 pwd: 0 c377: 377 ; Bits in rprinter interpreted as follows: ; 0 Debuggee acks debugger writes during normal operation ; 3 Debuggee acks debugger writes during booting ; 4 Debuggee's direction bit: 0 = from debuggee (debuggee's ; outputs enabled); 1 = to debuggee ; 10:17 data byte ; Bits in wprinter interpreted as follows: ; 0 Write strobe ; 1 Acknowledge debuggee write ; 2 Boot debuggee' (always 1 unless booting) ; 3 Mouse halt request ; 7 Debugger's direction bit: 0 = from debugger; 1 = to debugger .d0recvword: sta 3 1 2 jsr @GetFrame 10 jsr @StArgs jsr .d0recvbyte 0 sta 0 4 2 jsr .d0recvbyte 0 lda 1 c377 and 1 0 lda 3 4 2 ands 3 1 add 1 0 jsr @Return ; Must enter with debugger's direction bit set to 1--since this is only ; changed when writes are done, it will be. .d0recvbyte: inc 3 3 sta 3 1 2 ; Save return lda 3 cm100 lda 1 c4000 ; look for PO[07] d0rb1: rprinter and# 0 1 snr jmp d0rb2 ; PO[07] is low - D0 is sending inc 3 3 szr jmp d0rb1 ; D0 not sending--not an error since d0recvbyte is called while the D0 ; is running, to see if it stopped. lda 0 c252 jmp @1 2 d0rb2: lda 3 c377 and 3 0 sta 0 2 2 ; save complete byte lda 0 c60400 wprinter ; send write ack with boot bit high lda 3 cm100 d0rb3: rprinter ; ...and wait for debuggee to stop sending and# 0 1 szr jmp d0rb4 ; #4000 is high--D0 has stopped sending inc 3 3 szr jmp d0rb3 lda 3 @lvMCTimeOut ; D0 is hung up sending isz 0 3 ; Count failures in COMM-ER0 word 0 jmp .+1 d0rb4: lda 0 c20400 ; Drop write ack--D0 should go about its business wprinter lda 0 2 2 jmp @1 2 .d0sendword: sta 3 2 2 sta 0 pwd movs 0 0 jsr .d0sendbyte 1 lda 0 pwd lda 3 2 2 .d0sendbyte: sta 3 1 2 lda 1 c377 and 1 0 ; Mask out high bits lda 1 c20000 add 1 0 ; Byte to be sent + boot' bit sta 0 pbyte lda 3 cm100 lda 1 c4000 d0sb0: rprinter and# 0 1 szr ; Skip if debugee is sending jmp d0sb1 inc 3 3 szr jmp d0sb0 lda 3 @lvMCTimeOut ; D0 is hung up sending isz 1 3 ; Count failures in COMM-ER0 2nd word jmp .+1 d0sb1: lda 0 pbyte ; Strobe byte into PD register wprinter ; Byte without strobe lda 1 c100000 add 1 0 wprinter ; Byte with write strobe lda 3 cm100 d0sb2: rprinter ; Loop until debuggee acknowledges movl 0 0 szc jmp d0sb3 ; #100000--debuggee claims it got the data inc 3 3 szr jmp d0sb2 lda 3 @lvMCTimeOut ; D0 never responded isz 2 3 ; Count failures in COMM-ER1 1st word jmp .+1 d0sb3: lda 0 c20400 ; Drop strobe, clear data, open bus wprinter lda 3 cm100 ; Wait for debuggee to drop ack d0sb4: rprinter movl 0 0 snc ; Wait for debuggee's acknowledge to turn off jmp d0sbx inc 3 3 szr jmp d0sb4 lda 3 @lvMCTimeOut ; Debuggee never removed ack isz 3 3 ; Count failures in COMM-ER1 2nd word jmp .+1 d0sbx: lda 3 1 2 jmp 1 3 c4000: 4000 c60400: 60400 c20400: 20400 c20000: 20000 c100000: 100000 .ReadPrinter: rprinter jmp 1 3 .WritePrinter: wprinter jmp 1 3 .end