;; ShowCharMc.Mu -- Spruce inner loop ; Instruction positioning !1,2, useTest, GetChar1; !1,2, gc1, FullReturn; !1,2, GetOld, GetNew; !1,2, RangeError, notTooLow; !1,2, notTooHigh, RangeError2; !1,2, chk1, OffPage; !1,2, chk11, Double; !1,2, chk2, RangeError3; !1,2, OffPage2, chk3; !1,2, noCarry, Carry; !1,2, noCarryB, CarryB; !1,2, RecordUses, noRecord; !1,2, old, new; !1,2, OnCopy, enter1; !1,2, BufFull, GetChar; ShowChars: L_PC; savedPC_L; L_177026, TASK; PC_L; *4+entry* ;; let c=not immediate? WindowReadByte(DL), immediate>0? DL>>Bytes^i, DL>>STR.char^i GetChar1: L_ct-1, :gc2; [*3max* here] GetChar: L_ct-1; gc2: ct_L, SH<0; L_byteIdx+1, BUSODD, :gc1; [gc1, FullReturn*5*] ; Fetch new word or use old one gc1: byteIdx_L, :GetOld; [GetOld, GetNew] GetOld: T_377; L_T_data.T, :PlaceChar; GetNew: temp_L RSH 1; T_base; MAR_temp+T; NOP; available ;available ;available L_MD; data_L, TASK; temp_L LCY 8; *13* T_377; L_T_temp.T, :PlaceChar; ;; if c < bc % c > ec then {resultis 1} ; too high or too low PlaceChar: c_L; L_bcM1-T; L_ec-T, SH<0; ;; let icc=c+ICCOffset L_ICCOffset+T, SH<0, :RangeError; [RangeError*12*, notTooLow] ;; let p=WidthPointer+c*(size CharWidth/16) notTooLow: icc_L, L_T, :notTooHigh ; [notTooHigh, RangeError1*13*] notTooHigh: L_LASTL+T; ; next sequences makes c lsh 3 -- here, L=c lsh 1 temp_L LSH 1; ; temp=c lsh 2 L_T_temp; L_LASTL+T; ; L=c lsh 3 T_WidthPointer; L_LASTL+T, TASK; p_L; *18* ;; let b=CurB!0+p>>CharWidth.OB T_5; ; read 5, then 4 MAR_p+T; T_CurB0; ;available ;available L_MD+T; T_MD; b_L; ;; ShowChars, contd. ;; let s=CurS!0+p>>CharWidth.OS (sort of) ;; let band=s rshift 4 (sort of) ; actually, lineBand = {s, above} RROT 4 L_CurS0+T; T_LASTL; temp_L MRSH 1; L_T_temp; temp_L MRSH 1; L_T_temp; temp_L MRSH 1; L_T_temp, TASK; lineBand_L MRSH 1; *17* ;; let ds, db =p>>CharWidth.DS, p>>CharWidth.DB T_6; MAR_p+T; ;; test b < 4096 & ... T_b; L_7777-T; L_MD, SH<0; AC2_L, :chk1; [chk1, OffPage*6* ] chk1: L_MD, BUS=0, TASK; AC1_L, :chk11; *8* [chk11, Double ] ;; test db>0 & band ls nVisibleBands or resultis 2 chk11: L_AC1-1; T_7777, SH<0; L_lineBand AND T, :chk2; [chk2, RangeError3*3*] chk2: band_L; T_nVisibleBands; L_LASTL-T; ;; BandFree!0=100000b+icc //First entry MAR_BandFree, SH<0; T_100000, :OffPage2; [OffPage2*8*,chk3] band>nVisibleBands chk3: L_icc+T, TASK; MD_LASTL; *10* ;; BandFree!1=(s lshift 12)+b T_170000; MAR_BandFree+1; T_lineBand.T; L_b+T, TASK; MD_LASTL; *5* ;; DoubleAdd(CurS, lv p>>CharWidth.WS) Double: MAR_T_p+1; L_2+T; p_L; T_CurS1; L_MD+T; CurS1_L, ALUCY; T_CurS0, :noCarry; [noCarry, Carry] Carry: T_0+T+1; noCarry: L_MD+T; ;; DoubleAdd(CurB, lv p>>CharWidth.WB) MAR_p; CurS0_L; T_CurB1; ; available L_MD+T; CurB1_L, ALUCY; T_CurB0, :noCarryB; [noCarryB, CarryB] CarryB: T_0+T+1; noCarryB: L_MD+T, TASK; CurB0_L; *18* ;; ShowChars, contd. ;; if db eq 0 then goto GetChar... SINK_AC1, BUS=0; ;; if ICCUses!icc ge 0 then . . . T_icc, :useTest; [useTest, GetChar1] useTest: MAR_L_ICCUses+T; uses_L; L_2; entryLen_L; enter a 2-long value L_MD; SH<0, TASK; temp_L, :RecordUses; [RecordUses, noRecord]; *9* RecordUses: L_77, SWMODE; AC0_L, :MUL; db*ds+3*16+15 Mret: L_AC1; T_AC0; AC1_ L MRSH 1, L_T; (. . .) /16 AC0_ L RSH 1; L_AC1; T_AC0; AC1_ L MRSH 1, L_T; AC0_ L RSH 1; L_AC1; T_AC0; AC1_ L MRSH 1, L_T; AC0_ L RSH 1; L_AC1; T_AC0, TASK; AC1_ L MRSH 1; *17* T_EvenMask; (. . .)&(177776) // even number SINK_temp, BUS=0; T_AC1.T, :old; [old, new] new: L_fspn+T; fspn_L, :sto; old: L_fspo+T; fspo_L; sto: MAR_uses; T_2; L_temp-T, TASK; MD_LASTL, :noRecord; *10* ;; BandEnter(band, size BEChar/16) -- JMPRAM 30 enters here -- ;; onlyOnCopy, band, BandTable, CopyTable , BandFree, BandAvail, entryLen set up BandEnter: L_0; ct_L; force return right away L_PC, TASK; savedPC_L; *2* noRecord: SINK_onlyOnCopy, BUS=0; T_band, :OnCopy ;[OnCopy, enter1] ; Count contributions to jump for this band OnCopy: MAR_L_CopyTable+T; temp_L; T_entryLen; ;available L_MD+T; MAR_temp; TASK; ;available MD_LASTL; *11* T_band; enter1: MAR_BandTable+T; T_entryLen+1; ; MD_BandFree; SINK_MD; L_MD; MAR_BandFree-1; temp_L; L_BandFree+T; MD_temp; BandFree_L; L_BandAvail+T; BandAvail_L, SH<0, TASK; :BufFull; [BufFull*0*,GetChar] *16max* !1, 1, CodeReturn; Kill pending branches FullReturn: L_0, TASK, :CodeReturn; [CodeReturn, CodeReturn] $MUDone $0 RangeError: L_MUCharRange, TASK, :CodeReturn; . . . RangeError2: L_MUCharRange, TASK, :CodeReturn; . . . RangeError3: L_MUCharRange, TASK, :CodeReturn; OffPage: L_MUOffPage, TASK, :CodeReturn; OffPage2: L_MUOffPage, TASK, :CodeReturn; BufFull: L_MUBufFull, TASK, :CodeReturn; CodeReturn: AC0_L; *15max* L_savedPC, TASK; PC_L, :NOVEM; *9* ; FlushChars !1,2, flDoit, flDone; !1,2, flNotCh, flCh; !1,2, flW2, flW4; !1,2, flOLp, flCant; !1,2, flGoOn, FlushLoop; FlushChars: T_177777; L_leftCt XOR T, TASK; leftCt_L; ** convert from -(# left+1) to #left FlushLoop: MAR_p-1, SINK_p, BUS=0; L_p, :flDoit; [flDoit, flDone] flDoit: pData_L; MD_0; clear pointer entry SINK_MD; switch back to original address (could use if orig. was even!) L_MD; MAR_p; p_L; ready for next time! ;available ;available L_MD, TASK; typeWd_L; *12* L_typeWd; T_37, SH<0; T_LASTL.T, :flNotCh; [flNotCh, flCh] flNotCh: L_BERectangleH-T; NOP, SH=0; flCh: L_T_3, :flW2; [flW2, flW4] flW2: L_T_ONE; flW4: numData_L; L_leftCt-T-1; SH<0, TASK; leftCt_L, :flOLp; *11max* [flOLp, flCant] flOLp: MAR_L_outAddr+1; outAddr_L; L_numData-1, BUS=0; MD_typeWd, :flGoOn; [flGoOn,FlushLoop] flGoOn: MAR_pData+1; numData_L; L_pData+1; pData_L; L_MD, TASK; typeWd_L, :flOLp; *10* !1,1,FlushReturn; ; This can almost certainly be bummed -- reverse change to leftCt (ugh!) flCant: T_numData; L_leftCt+T+1; leftCt_L; L_MUCant, TASK, :FlushReturn; flDone: L_0, TASK, :FlushReturn; MUDone ; odd-aligned to kill branches FlushReturn: AC0_L; ** T_177777; L_leftCt XOR T, TASK; leftCt_L, :NOVEM; ** convert #left to -(#left+1) ;; DCS, September 29, 1978 8:50 AM, derived from ShowCharacter in SpruceShow ;; October 2, 1978 7:20 PM, working away -- getting faster! ;; October 3, 1978 11:12 AM, define regs (used all!), last minor mods before assembly test ;; October 3, 1978 2:43 PM, repairs after deskcheck ;; October 4, 1978 10:10 AM, bugs in setup code (4, 1 a typo) ;; October 4, 1978 5:18 PM, bug in onCopy dispatch (wrong order -- a typo), and fspn/o calc (off by 2x) ;; October 5, 1978 8:30 AM, correct OrbitSizeChar computation ;; October 5, 1978 9:45 AM, ShowChars updates BandFree, BandAvail, each time out; ;; fetches same each time in ;; October 5, 1978 11:11 AM, double store must happen one cycle earlier! Good! ;; October 18, 1978 12:17 PM, remove all setup code -- use RLoad, Store instructions instead ;; October 20, 1978 11:57 AM, move defs to SpruceDefs ;; October 22, 1978 12:00 AM, add FlushChars ;; October 23, 1978 7:01 AM, complement leftCt in and out (easier than in ML code) ;; October 24, 1978 8:51 AM, update CopyTable!band if onlyOnCopy -- remove branching hair from flush ;; October 24, 1978 9:17 AM, add linkage allowing enter microcode to be used as BandEnter ;;