; mxa.asm -- Midas/Maxc2 interface procedures ; E. R. Fiala and E. A. Taft / March 1976 ; !!!!!!!! Warning -- These procedures are not reentrant !!!!!!!!!! .ent XctR4 ; Read registers of various sizes .ent XctR8 .ent XctR9 .ent XctR12 .ent XctR18 .ent XctR20 .ent XctR36 .ent XctL4 ; Write registers of various sizes .ent XctL8 .ent XctL9 .ent XctL12 .ent XctL18 .ent XctL20 .ent XctL36 .ent XctMic ; Execute a microinstruction .ent RestoreMRegs ; Restore registers after memory read/write .ent ConvertAV ; Unpack AddrVec into MADDRL and MADDRH ; and load registers to address memory .ent SetIMLd .ent SetIMRd .ent ZeroCore .ent ADREG ; Indirect word for SMI address register .ent INREG ; Indirect word for SMI input .ent OUTREG ; Indirect word for SMI output .ent LDRMEM ; Points at word 0 of LDR memory .ent ITRCNT ; LDR COUNT .ent INSTST ; LDR TSTINS .ent MEMCFG ; LDR CONFIG .ent ADRANG ; LDR ARANGE .ent GOODD ; Test write data .ent ACTD ; Test read data .ent DMASK ; Test comparison mask .ent RANDATA ; Static for random number generator .ent RANDIX ; Another random number generator static .ent PATTERN ; Index for data test pattern .ent LOWADDR ; Low address for memory tests .ent HIGHADDR ; High address for memory tests .ent TAVEC ; Address vector for memory tests .ent TestWidth ; Width of register or memory being tested .ent REGACT ; Vector of register actions .ent MEMACT ; Vector of memory actions .ent PATACT ; Vector of pattern actions .ent QUITact ; Action static for abort .ent QuitF ; EveryTimeList static .ent TMP ; Four-word vectors beginning at even words .ent TMP1 .ent TMP2 .ent CUM ; Three-word vector containing 36-bit 400 .ent SMFORF ; Vector holding value for SMFORF = SM 377 .ent F ; Vector holding value for F .ent Q ; Vector holding value for Q .ent EREG ; Vector holding value for EREG .ent STK ; Vector holding 12 STK registers .ent NPC ; Static holding value for NPC .ent IMA ; Static holding value for IMA .ent Y ; Static holding value for Y .ent X ; Static holding value for X .ent MADDRL ; Static holding low 16 bits of memory address .ent MADDRH ; Static holding high 16 bits of memory address .ent LADDR ; Static holding LDR displacement for MADDRL .ent MAINsize ; Static holding max. MADDRH for MAIN .ent MEMNAM ; Table of memory names .ent MName .ent MEMWID ; Table of memory widths .ent MEMFORMS ; Table of memory output format vectors .ent MForm .ent MEMLEN ; Table of memory lengths .ent REGNAM ; Table of register names .ent RName .ent REGWID ; Table of register widths .ent REGFORMS ; Table of register output format vectors .ent RForm B0 = 203 ; SMI addresses B1 = 202 B2 = 201 CR = 210 BR0 = 213 BR1 = 212 BR2 = 211 PIR0 = 217 PIR1 = 216 PIR2 = 215 PIR3 = 214 BRNIMA = 151 ; Addresses in LDRMEM of microinstructions LDX = 170 LDY = 202 LDQ = 214 SETFLY = 221 LDNPC = 226 LDEREG = 303 LDSMF = 322 CLRFLY = 327 SETFLQ = 334 CLRFLQ = 341 LDRSIZE = 130 ; Size of LDR memory .TXTM B .srel XctMic: .XctMic XctR4: .XctR4 XctR8: .XctR8 XctR9: .XctR9 XctR12: .XctR12 XctR18: .XctR18 XctR20: .XctR20 XctR36: .XctR36 XctL4: .XctL4 XctL8: .XctL8 XctL9: .XctL9 XctL12: .XctL12 XctL18: .XctL18 XctL20: .XctL20 XctL36: .XctL36 RestoreMRegs: .RestoreMRegs ConvertAV: .ConvertAV SetIMLd: .SetIMLd SetIMRd: .SetIMRd ZeroCore: .ZeroCore ; **This method of definition only works if all references to the ; statics occur after the definitions** MForm: Form36 Form36 FormIM Form36 FormDM 0 Form40 Form36 Form36 0 FormDM FormDM FormLDR Form36 RForm: 0 0 0 Form36 Form36 Form36 0 0 Form40 0 Form40 Form36 0 0 Form36 0 Form36 MName: IMhn IMln IMn SMn DMn MPn MAINn RMn LMn STKn DM1n DM2n LDRn KSTATn RName: Xn ACn Yn Pn Qn Fn NPCn MARn MDRn KMARn KMDRn ARMn IMAn KUNITn EREGn BPCn P1n .zrel ; Page 0 stuff ADREG: 177400 ; SMI address register INREG: 177401 ; SMI input register OUTREG: 177403 ; SMI output register ; 177402 OUTREGP ; 177404 ERRINF ; 177405 ERRENB LDRMEM: 0 ; Vectors initialized by InitMpCode ITRCNT: 0 INSTST: 0 MEMCFG: 0 ADRANG: 0 GOODD: 0 ACTD: 0 DMASK: 0 CUM: .CUM RANDATA: 0 RANDIX: 0 PATTERN: 0 LOWADDR: 0 HIGHADDR: 0 TAVEC: 0 TestWidth: 0 REGACT: 0 MEMACT: 0 PATACT: 0 QUITact: 0 QuitF: 0 TMP: 0 TMP1: 0 TMP2: 0 Q: 0 ; Vectors for microprocessor state F: 0 EREG: 0 SMFORF: 0 STK: 0 IMA: 0 ; Statics for microprocessor state NPC: 0 X: 0 Y: 0 LADDR: 0 MADDRL: 0 MADDRH: 0 MAINsize: 17 MEMNAM: 0 MEMLEN: .MLen ; Table of memory lengths indexed by MemX MEMWID: .MWid MEMFORMS: 0 REGNAM: 0 REGWID: .RWid REGFORMS: 0 .nrel .CUM: 0 20 0 Form36: 2 0 22 22 22 Form40: 3 0 4 4 22 26 22 FormIM: 4 0 22 22 22 44 22 66 22 FormDM: 3 0 14 14 14 30 14 FormLDR: 5 0 10 10 22 32 22 54 22 76 22 IMhn: .txt "IM[0,35]" IMln: .txt "IM[36,71]" IMn: .txt "IM" SMn: .txt "SM" DMn: .txt "DM" MPn: .txt "MP" MAINn: .txt "MAIN" RMn: .txt "RM" LMn: .txt "LM" STKn: .txt "STK" DM1n: .txt "DM1" DM2n: .txt "DM2" LDRn: .txt "LDR" KSTATn: .txt "KSTAT" .MWid: 44 44 110 44 44 22 50 44 44 14 44 44 120 44 Xn: .txt "X" ACn: .txt "AC" Yn: .txt "Y" Pn: .txt "P" Qn: .txt "Q" Fn: .txt "F" NPCn: .txt "NPC" MARn: .txt "MAR" MDRn: .txt "MDR" KMARn: .txt "KMAR" KMDRn: .txt "KMDR" ARMn: .txt "ARM" IMAn: .txt "IMA" KUNITn: .txt "KUNIT" EREGn: .txt "EREG" BPCn: .txt "BPC" P1n: .txt "P1" .RWid: 10 4 11 44 44 44 14 24 50 24 50 44 14 3 44 24 44 ; Procedures to read registers of various widths ; XctR4(LdrAddr,DataVec) .XctR4: sta 3 save3 jsr .XctMR 1 jmp XctRd ; XctR20(LdrAddr,DataVec) .XctR20: sta 3 save3 jsr .XctMR 1 jmp XctRc ; XctR18(LdrAddr,DataVec) .XctR18: sta 3 save3 jsr .XctMR 1 lda 3 save1 lda 0 .B1 sta 0 @ADREG lda 0 @INREG lda 1 .B2 sta 1 @ADREG lda 1 @INREG coms 1 1 movzl 1 1 coml 0 0 movl 1 1 movl 0 0 sta 0 0 3 lda 0 c140000 and 1 0 sta 0 1 3 jmp XctRb ; XctR8(LdrAddr,DataVec) .XctR8: sta 3 save3 jsr .XctMR 1 lda 0 .B1 sta 0 @ADREG lda 0 @INREG com 0 0 lda 3 c17 ands 3 0 lda 1 .B2 sta 1 @ADREG lda 1 @INREG com 1 1 lda 3 c360 and 3 1 add 1 0 cycle 4 jmp XctRa ; XctR9(LdrAddr,DataVec) .XctR9: sta 3 save3 jsr .XctMR 1 lda 0 .B1 sta 0 @ADREG lda 0 @INREG com 0 0 lda 3 c37 ands 3 0 lda 1 .B2 sta 1 @ADREG lda 1 @INREG com 1 1 lda 3 c360 and 3 1 add 1 0 cycle 3 jmp XctRa ; XctR12(LdrAddr,DataVec) .XctR12: sta 3 save3 jsr .XctMR 1 lda 0 .B1 sta 0 @ADREG lda 0 @INREG com 0 0 lda 3 c377 ands 3 0 lda 1 .B2 sta 1 @ADREG lda 1 @INREG com 1 1 lda 3 c360 and 3 1 add 1 0 jmp XctRa ; XctR36(LdrAddr,DataVec) .XctR36: sta 3 save3 jsr .XctMR 1 lda 0 .B0 sta 0 @ADREG lda 0 @INREG com 0 0 sta 0 @save1 isz save1 XctRc: lda 0 .B1 sta 0 @ADREG lda 0 @INREG com 0 0 sta 0 @save1 isz save1 XctRd: lda 0 .B2 sta 0 @ADREG lda 0 @INREG com 0 0 lda 1 c360 ands 1 0 XctRa: sta 0 @save1 XctRb: lda 3 save3 jmp 1 3 c37: 37 c17: 17 c140000: 140000 c360: 360 .B0: B0 .B1: B1 .B2: B2 save3: 0 save1: 0 ; XctMic(LdrAddr) -- Execute a microinstruction .XctMR: sta 1 save1 .XctMic: sta 3 1 2 xctm1: lda 3 LDRMEM ; Compute lv LDRMEM!LdrAddr add 0 3 lda 1 .PIR0 sta 1 @ADREG lda 1 0 3 sta 1 @OUTREG lda 1 .PIR1 sta 1 @ADREG lda 1 1 3 sta 1 @OUTREG lda 1 .PIR2 sta 1 @ADREG lda 1 2 3 sta 1 @OUTREG lda 1 .PIR3 sta 1 @ADREG lda 1 3 3 sta 1 @OUTREG lda 1 .CR sta 1 @ADREG lda 1 4 3 com 1 1 ; Complement the control signals sta 1 @OUTREG lda 3 1 2 jmp 1 3 .PIR0: PIR0 .PIR1: PIR1 .PIR2: PIR2 .PIR3: PIR3 .CR: CR .BR0: BR0 .BR1: BR1 .BR2: BR2 c77000: 77000 c17740: 17740 c377: 377 ; Procedures to load registers of various widths ; XctL4(LdrAddr,DataVec) .XctL4: sta 3 1 2 mov 1 3 jmp XctLa ; XctL20(LdrAddr,DataVec) .XctL20: sta 3 1 2 mov 1 3 jmp XctLc ; XctL8(LdrAddr,DataVec) .XctL8: sta 3 1 2 sta 0 2 2 mov 1 3 lda 0 .BR1 sta 0 @ADREG lda 0 0 3 com 0 0 cycle 4 sta 0 @OUTREG lda 0 .BR2 sta 0 @ADREG lda 0 0 3 cycle 12. XctLb: com 0 0 sta 0 @OUTREG lda 0 2 2 jmp xctm1 ; XctL9(LdrAddr,DataVec) .XctL9: sta 3 1 2 sta 0 2 2 mov 1 3 lda 0 .BR1 sta 0 @ADREG lda 0 0 3 com 0 0 cycle 5 sta 0 @OUTREG lda 0 .BR2 sta 0 @ADREG lda 0 0 3 cycle 13. jmp XctLb ; Load procedures (cont'd) ; XctL12(LdrAddr,DataVec) .XctL12: sta 3 1 2 sta 0 2 2 mov 1 3 lda 0 .BR1 sta 0 @ADREG lda 0 0 3 coms 0 0 sta 0 @OUTREG lda 0 .BR2 sta 0 @ADREG lda 0 0 3 jmp XctLb ; XctL18(LdrAddr,DataVec) .XctL18: sta 3 1 2 mov 1 3 lda 1 .BR1 sta 1 @ADREG lda 1 0 3 lda 3 1 3 comzr 1 1 comr 3 3 movzr 1 1 movr 3 3 movs 3 3 sta 1 @OUTREG lda 1 .BR2 sta 1 @ADREG sta 3 @OUTREG xctm1a: jmp xctm1 XctMica: jmp .XctMic ; XctL36(LdrAddr,DataVec) .XctL36: sta 3 1 2 mov 1 3 lda 1 .BR0 sta 1 @ADREG lda 1 0 3 com 1 1 sta 1 @OUTREG inc 3 3 XctLc: lda 1 .BR1 sta 1 @ADREG lda 1 0 3 com 1 1 sta 1 @OUTREG inc 3 3 XctLa: lda 1 .BR2 sta 1 @ADREG lda 1 0 3 coms 1 1 sta 1 @OUTREG jmp xctm1a ; Address memory routines used from ConvertAV ; They finish by either returning to 1 3 or jumping to RetMemX ; AdrRL() ; XctL8(LDX,lv(MADDRL lshift 8)) AdrRL: movs 0 0 sta 0 @TMP ; Use vector TMP to hold MADDRL lshift 8 lda 0 .LDX LDA 1 TMP jmp .XctL8 ; AdrIM() = XctL12(LDNPC,lv(MADDRL lshift 4)); XctMic(BRNIMA) AdrIM: cycle 4 sta 0 @TMP lda 0 .LDNPC lda 1 TMP jsr .XctL12 2 lda 0 .BRNIMA jsr XctMica 1 jmp RetMemX ; AdrSM() = XctL9(LDY,lv(MADDRL lshift 7)) AdrDM: AdrSM: cycle 7 sta 0 @TMP lda 0 .LDY AdSMP: lda 1 TMP jsr .XctL9 2 jmp RetMemX ; AdrMP() ; XctL36(LDQ,CUM); XctMic(LDSMF) ; XctL9(((MADDRL & 1000B) ne 0 ? SETFLY,CLRFLY),MADDRL) AdrMP: lda 0 .LDQ lda 1 CUM jsr .XctL36 2 lda 0 .LDSMF jsr XctMica ; SMFORF ← CUM 1 lda 0 MADDRL cycle 7 sta 0 @TMP ; TMP ← MADDRL for XctL9(LDY,TMP) lda 1 MADDRL lda 3 c1000 lda 0 .CLRFLY and 1 3 szr lda 0 .SETFLY ; F[CUM] ← leading bit in MADDRL jmp AdSMP ; AdrMAIN() ; TMP!0 = (MADDRH lshift 12) + (MADDRL rshift 4) ; TMP!1 = MADDRL lshift 12 AdrMAIN: lda 0 MADDRH cycle 14 lda 3 c170000 and 0 3 ; 1/ MADDRH lshift 12 lda 0 MADDRL cycle 14 sta 0 2 2 lda 1 c7777 and 1 0 ; 0/ MADDRL rshift 4 add 3 0 lda 3 TMP sta 0 0 3 lda 0 2 2 lda 1 c170000 and 1 0 sta 0 1 3 jmp RetMemX ; AdrLDR() ; LADDR = MADDRL*5 + LDRMEM AdrLDR: lda 0 LDRMEM lda 1 MADDRL add 1 0 addzl 1 1 add 1 0 sta 0 LADDR jmp 1 3 c170000: 170000 c7777: 7777 c3: 3 c1: 1 c20: 20 c1000: 1000 save3a: 0 .LDNPC: LDNPC .BRNIMA: BRNIMA .LDX: LDX .LDSMF: LDSMF .CLRFLY: CLRFLY .SETFLY: SETFLY .SETFLQ: SETFLQ .CLRFLQ: CLRFLQ .LDY: LDY .LDQ: LDQ .LDEREG: LDEREG .IMA: IMA .NPC: NPC .X: X .Y: Y lvXctR36: XctR36 ; ConvertAV(AddrVec,MemX) = valof ; MADDRH = AddrVec!0; MADDRL = AddrVec!1 ; test (MemX eq 6) ; ifso if MADDRH > MAINsize then resultis false ; ifnot if MADDRL ge table [ 4000B; 4000B; 4000B ; 1000B; 1000B; 2000B; 0B; 40B; 40B; 14B; LDRSIZ ] ! MemX ; % (MADDRH ne 0) then resultis false ; switchon MemX into ; [ ; case 0: case 1: case 2: AdrIM(); endcase ; case 3: AdrSM(); endcase ; case 10: case 11: case 4: AdrDM(); endcase ; case 5: AdrMP(); endcase ; case 6: AdrMAIN(); endcase ; case 7: case 8: AdrRL() ; case 9: endcase ; case 12: AdrLDR() ; case 13: endcase ; ] ; resultis MemX CvAV4: add 1 3 lda 1 16 3 ; Get memory size adcl# 0 1 szc ; Skip if AC1 gr AC0 jmp BadAdr ; no good jsr 0 3 ; ok, address it 0 RetMemX: lda 0 MemX ; resultis MemX lda 3 save3a jmp 1 3 ; Have MemX ne 6 in 1 CvAV3: lda 0 MADDRL jsr CvAV4 MAddr: jmp AdrIM jmp AdrIM jmp AdrIM jmp AdrSM jmp AdrDM jmp AdrMP jmp BadAdr jmp AdrRL jmp AdrRL jmp RetMemX jmp AdrDM jmp AdrDM jmp AdrLDR jmp RetMemX .MLen: 10000 ; IM[0,35] 10000 ; IM[36,71] 10000 ; IM[0,71] 1000 ; SM 1000 ; DM 2000 ; MP 0 ; MAIN (unused) 40 ; RM 40 ; LM 14 ; STK 1000 ; DM1 1000 ; DM2 LDRSIZE ; LDR 10 ; KSTAT .ConvertAV: sta 3 save3a sta 1 MemX mov 0 3 ; 3←AddrVec lda 0 NMems ; Number of memories -1 subl# 1 0 szc ; Skip if AC1 le AC0 jmp BadAdr lda 0 1 3 sta 0 MADDRL ; Low part of address lda 0 MainMemX sub# 1 0 szr ; Skip if MAIN address (else high part ignored) jmp CvAV3 lda 0 0 3 sta 0 MADDRH ; High part of address add# 0 0 snr ; Skip if high part non-0 jmp AdrMAIN lda 3 MAINsize subl# 0 3 snc ; Skip if AC0 > AC3 jmp AdrMAIN ; OK BadAdr: mkminusone 0 0 ; return -1 if no good lda 3 save3a jmp 1 3 MemX: 0 MainMemX: 6 NMems: 15 ; Number of memories -1 ; Subroutine to restore registers clobbered incidentally during memory read/load ; RestoreMRegs(MemX) ; switchon MemX into [ ; case 0: ; case 1: ; case 2: XctL12(LDNPC,lv IMA); XctL12(BRNIMA,lv NPC); endcase ; case 3: ; case 4: case 10: case 11: XctL9(LDY,lv Y); XctL36(LDQ,Q); endcase ; case 5: XctL36(((F!1 & 20B) ne 0 ? SETFLQ,CLRFLQ),SMFORF) ; XctMic(LDSMF); XctL36(LDQ,Q); XctL9(LDY,lv Y); endcase ; case 7: ; case 8: XctL8(LDX,lv X); XctL36(LDQ,Q); endcase ; default: return ; ] ; XctL36(LDEREG,EREG); @ADREG = 0; return ResIM: lda 0 .LDNPC lda 1 .IMA jsrii lvXctL12 2 lda 0 .BRNIMA lda 1 .NPC jsrii lvXctL12 2 Resfx: lda 0 .LDEREG lda 1 EREG jsrii lvXctL36 2 mkzero 0 0 sta 0 @ADREG Resfin: lda 3 save3a jmp 1 3 ResMP: lda 3 F lda 1 1 3 lda 3 c20 lda 0 .CLRFLQ and 3 1 szr ; CLEARF[CUM] if restoring CUM=0 lda 0 .SETFLQ ; SETF[CUM] if restoring CUM=1 lda 1 SMFORF jsrii lvXctL36 2 lda 0 .LDSMF ; SMFORF ← Q jsrii lvXctMic 1 ResSM: ResDM: lda 0 .LDY ; Restore Y lda 1 .Y jsrii lvXctL9 2 jmp ResSD ResRL: lda 0 .LDX lda 1 .X jsrii lvXctL8 2 ResSD: lda 0 .LDQ lda 1 Q jsrii lvXctL36 2 jmp Resfx .RestoreMRegs: sta 3 save3a jsr ResMa jmp ResIM ;0 IM[0,35] jmp ResIM ;1 IM[36,71] jmp ResIM ;2 IM[0,71] jmp ResSM ;3 SM jmp ResDM ;4 DM jmp ResMP ;5 MP jmp Resfin ;6 MAIN jmp ResRL ;7 RM jmp ResRL ;8 LM jmp Resfin ;9 STK jmp ResDM ;10 DM1 jmp ResDM ; 11 DM2 jmp Resfin ;12 LDR jmp Resfin ;13 KSTAT ResMa: add 0 3 jmp 0 3 lvXctL8: XctL8 lvXctL9: XctL9 lvXctL12: XctL12 lvXctL36: XctL36 lvXctMic: XctMic ; SetIMLd(DataVec) ; DataVec!0 = DataVec!0 xor 177760B ; let A = DataVec!2 lshift 4 ; let B = DataVec!3 lcy 4 ; let C = DataVec!4 lcy 4 ; TMP!0 = A+(B & 17B) ; TMP!1 = (B & 177760B)+(C & 17B) ; TMP!2 = C & 177760B .SetIMLd: sta 3 1 2 sta 2 save2c mov 0 3 ; AC3 = DataVec lda 2 TMP lda 0 4 3 cycle 4 ; DataVec!4 lcy 4 lda 1 D177760 and 0 1 sta 1 2 2 ; TMP!2 = DataVec!4 lshift 4 lda 1 D17 and 1 0 sta 0 1 2 ; TMP!1 = DataVec!4 rshift 12 lda 0 3 3 cycle 4 ; DataVec!3 lcy 4 lda 1 D177760 and 0 1 sta 1 0 2 ; TMP!0 = DataVec!3 lshift 4 lda 1 D17 and 1 0 ; AC0 = DataVec!3 rshift 12 lda 1 2 3 movzl 1 1 movzl 1 1 movzl 1 1 movzl 1 1 ; DataVec!2 lshift 4 add 0 1 ; AC1 = (DataVec!2 lshift 4)+(DataVec!3 rshift 12) lda 0 0 2 sta 1 0 2 lda 1 1 2 add 1 0 sta 0 1 2 ; TMP!1 = (DataVec!3 lshift 4)+(DataVec!4 rshift 12) FixBA: lda 0 0 3 lda 1 D177760 mov 0 2 ; DataVec!0 andzl 1 2 add 1 0 sub 2 0 sta 0 0 3 ; DataVec!0 = DataVec!0 xor 177760B lda 2 save2c lda 3 1 2 jmp 1 3 save2c: 0 D17: 17 D177760: 177760 D7777: 7777 D170000: 170000 DX1: 0 ; SetIMRd(DataVec) ; DataVec!0 = DataVec!0 xor 177760B ; let A = TMP!0 lcy 12 ; let B = TMP!1 lcy 12 ; let C = TMP!2 rshift 4 ; DataVec!2 = DataVec!2 + (A & 7777B) ; DataVec!3 = (A & 170000B)+(B & 7777B) ; DataVec!4 = (B & 170000B)+C .SetIMRd: sta 3 1 2 sta 2 save2c mov 0 3 ; AC3 = DataVec lda 2 TMP lda 0 0 2 cycle 14 sta 0 DX1 ; DX1 = TMP!0 lcy 12 lda 0 1 2 cycle 14 ; AC0 = TMP!1 lcy 12 lda 2 2 2 movzr 2 2 movzr 2 2 movzr 2 2 movzr 2 2 ; AC2 = TMP!2 rshift 4 lda 1 D170000 and 0 1 ; AC1 = TMP!1 lshift 12 add 1 2 sta 2 4 3 ; DataVec!4 = (TMP!1 lshift 12)+(TMP!2 rshift 4) lda 1 D7777 and 1 0 ; AC0 = TMP!1 rshift 4 lda 1 DX1 lda 2 D170000 and 1 2 ; AC2 = TMP!0 lshift 12 add 2 0 sta 0 3 3 ; DataVec!3 = (TMP!0 lshift 12)+(TMP!1 rshift 4) lda 0 2 3 lda 2 D7777 and 2 1 add 0 1 sta 1 2 3 ; DataVec!2 = (TMP!0 rshift 4)+DataVec!2 jmp FixBA mfetch = 66000 mstore = 66001 mrmw = 66002 mblks = 66003 mfblk32 = 66004 msblk32 = 66005 mfblk40 = 66006 msblk40 = 66007 ; ZeroCore(AddrVec,Count) zeroes Maxc memory .ZeroCore: sta 3 1 2 ; Save return sta 1 2 2 ; Save word count jsr .+4 ; 3←DataVec (all zeroes) 0 0 0 mov 3 1 ; 1←DataVec lda 3 2 2 ; 3←Word count mblks ; Block transfer < 32K words lda 3 1 2 jmp 1 3 ; Return result in 0 .end