;CONVERT A BCPL STRING. ;CALL WITH CVRT(STRING POINTER,Xcoordinate, ;LWA-NWRDS,FONT,MAXWIDTH,MAXHEIGHT,NWRDS) ;RETURNS THE WIDTH OF THE STRING IN BITS, AND STORES ITS MAX ;HEIGHT IN MaxStringHeight ;OFFSETS IN THE FRAME STRINGPOINTER=4 Xstart=5 Ystart=6 LWA=7 FontPointer=10 Face = 11 ;Bit0-13 = position hardcopy, Bit 14 = make Bold, bit 15 = make Italics WidthPointer = 12 MagFlag = 13 fNwrds = 14 DBA = 15 Xposn=16 MicaPosn=17 currXposn=20 Char=21 CharPointer=22 height=23 MaxHeight=24 BoldFlg=25 OverHang=26 CHARSDONE=27 RET=30 .BEXTZ MaxStringHeight, HardCopy, ItalicsBuff, Mag, WindowYmin, WindowXmin .BEXTZ DisplayArea, SetBPtr, OnBits, OffBits, SetBMask, MaskTable .ENT Cvrt .SREL Cvrt: CSTRT .NREL CSTRT: STA 3 1 2 JSR@ 370 40 JSR@ 367 LDA 0 @STRINGPOINTER,2 LDA 1 C177400 ANDS 1 0 SNR JMP@ 366 STA 0 CHARSDONE,2 lda 1 Xstart,2 sta 1 Xposn,2; Xposn is updated to mica precision lda 0 ScreenYmax lda 1 Ystart,2 SUB 1 0 sta 0 MaxHeight,2; save ScreenYmax-Yposn in MaxHeight SUB 0 0 STA 0 MaxStringHeight STA 0 MicaPosn,2 STA 0 OverHang,2; set height to zero for non-italics strings sta 2 SavedAC2 DoRight: LDA 1 @STRINGPOINTER,2 JSR StartCvrt ISZ STRINGPOINTER,2 DSZ CHARSDONE,2 JMP DoLeft JMP DoExit DoLeft: LDA 1 @STRINGPOINTER,2 MOVS 1 1 JSR StartCvrt DSZ CHARSDONE,2 JMP DoRight ;return string length is screen bits ;AC0 _ (Xposn-Xstart) + Overhang/4 + BoldFace? 1,0 DoExit: lda 0 Xposn,2 lda 1 Xstart,2 sub 1 0 lda 3 Face,2; BoldFace bit is C14 lda 1 OverHang,2 movzr 1 1; divide OverHang by 2 add 3 1; add 2 to width calculation if boldface movzr 1 1; divide (OverHang + boldface) by 2 to set true overhang add 1 0 JMP@ 366 StartCvrt: STA 3 RET,2 LDA 3 C177; Mask the character code in AC1 AND 3 1 lda 0 HardCopy; check for hardcopy mode mov 0 0 SNR jmp DoCvrt ;MicaPosn = MicaPosn + WidthPointer!char ;Xposn = Xstart + MicaPosn*1778/50 SetBitPsn: STA 1 Char,2; save Char since I need the AC lda 3 WidthPointer,2 ADD 1 3 lda 0 0,3; get with from WidthPointer!char lda 1 MicaPosn,2 ADD 1 0 sta 0 MicaPosn,2; MicaPosn is updated to the new coordinate lda 2 C50; Now scale MicaPosn to required Alto Xposn value lda 0 C1778 MOVZR 0 0 MUL LDA 2 C1778 DIV MOV# 0,0; noop return for negative result lda 2 SavedAC2; ***AC2 restored lda 0 Xstart,2; add 0 1 sta 1 Xposn,2; jam mica computed value into Xposn lda 1 Char,2 DoCvrt: lda 0 Face,2; First check if Italics conversion is required and save BoldFlag movzr 0 0 SZC; Skip on carry generated 2 instructions back jmp DoItalics; ifso go make a "sliced" copy of the character definition sta 0 BoldFlg,2; save original bit 14 as the Bold Flag bit ContCvrt: LDA 3 FontPointer,2; assumes AC1 has character code in it ADD 1 3 STA 3 CharPointer,2; Save pointer to character pointer in font vor Convert LDA 0 0 3 ADD 0 3; NOW POINTS TO 2*WIDTH+1 OR PSEUDOCHAR STA 3 CharDef; Save pointer to character entry in font LDA 0 0 3; 2*WIDTH OR PSEUDO MOVZR 0 0 SNC LDA 0 C20; PSEUDO-CHAR. THIS PART'S WIDTH IS 16 LDA 1 Xposn,2 ADD 1 0 STA 0 Xposn,2; UPDATE WIDTH Save Xposn for current char in AC1 LDA 0 1 3; XH,HD FOR THIS CHARACTER MOVS 0 3 ADD 3 0 LDA 3 C377 AND 3 0; TOTAL HEIGHT BELOW ORIGIN LDA 3 MaxStringHeight; MAX HEIGHT SO FAR SGT 3 0 STA 0 MaxStringHeight; CURRENT IS BIGGER LDA 3 MaxHeight,2 ;MAXIMUM ALLOWED HEIGHT SGT 3 0 JMP MagCvrt; MagCvrt will clip at the screen boundaries LDA 3 ScreenXmax; See if part of the character lies to the right of the screen LDA 0 Xposn,2 SGT 3 0 JMP MagCvrt; MagCvrt will clip at the screen boundaries LDA 3 MagFlag,2; See if we need to do a Magnified Convert MOVZR 3 3 SZR JMP MagCvrt MOVZR 1 0; Now set up the required parameters ofe Convert MOVZR 0 0 MOVZR 0 0 MOVZR 0 0 LDA 3 LWA,2 ADD 3 0; WAD in AC0 for CONVERT LDA 3 C17; compute Xposn into DWA and DBA AND 3 1 SUB 1 3; DBA _ 15 - (BitPosn & #17) RpCONV: STA 3 DBA,2 LDA 3 CharPointer,2 CONVERT fNwrds JMP DoExtn; CHARACTER HAS AN EXTENSION DnCVRT: lda 3 BoldFlg,2 movzr 3 3 SNC JMP@ RET,2 MkBold: sta 3 BoldFlg,2; Bold characters are done by calling Convert again 1 bit to the right adc 3 3 addz 1 3 SZC jmp RpCONV inc 0 0 lda 1 C20 add 1 3 jmp RpCONV ScreenXmax: 576.; **As defined in Sil.defs (Nwrds*16) ScreenYmax: 762.; **As defined in Sil.defs DsiplaySize: 27432.; **As defined by Sil.defs (Nwrds*ScreenYmax) C177400: 177400 C377: 377 C237: 237 C177: 177 C20: 20 C17: 17 C50: 50.; This value must match SilPress.bcpl for screen to mica conversion C1778: 1778.; This value must match SilPress.bcpl for screen to mica conversion SavedAC2: 0 CharDef: 0 ;copy the entire character definition from the font to the ItalicsBuff DoItalics: sta 0 BoldFlg,2; save original bit 14 as the Bold Flag bit LDA 3 FontPointer,2; assumes AC1 has character code in it ADD 1 3 LDA 0 0 3 ADD 0 3; NOW POINTS TO 2*WIDTH+1 OR PSEUDOCHAR LDA 0 1,3; get the height LDA 1 C377 AND 0 1; mask to just the height and check for zero height sta 1 height,2 sta 1 OverHang,2; save max shift in OverHang inc 1 1; AC1 now has height+1 sub 1 3 mov 3 0 com 1 3; AC3 now has -(height+2) lda 1 ItalicsBuff inc 1 1; AC1 now points to ItalicsBuff+1 BLT lda 1 height,2 lda 3 ItalicsBuff sub 1 3 sta 3 Char,2 ;let height = XH ;[ ;ItalicsBuff!height = ItalicsBuff!height rshift (height/4) ;height = height-1 ;if height ls 4 then break ;] repeat ItalicsL: movzr 1 1 movzr 1 1 SNR; divide ht by 4 jmp exitItalics lda 0 @Char,2 jsr @347; rshift AC0 AC1 times sta 0 @Char,2 isz Char,2 dsz height,2 lda 1 height,2; set AC0 to -1 jmp ItalicsL exitItalics: lda 1 C237; put Dummmy char pointer into AC1 jmp ContCvrt DoExtn: sta 3 CharDef; save extended char in CharDef (CharDef is not used now) lda 3 BoldFlg,2 movzr 3 3 SZC JMP MkBold lda 1 CharDef jmp DoCvrt ; * * * * * * * * * * * * * * * * * * * ;The rest of the code implements a Magnified version of the Convert process ;Exit from MagCvrt -- put here for address range placement MagDn: lda 2 SavedAC2 lda 1 @CharDef movzr 1 1 szc jmp@ RET,2 jmp DoCvrt MagCvrt: sta 1 currXposn,2 ;let XH = -(CharDef!1 & #377) //number of scanlines to Convert lda 3 CharDef lda 3 1,3; CharDef!1 lda 1 C377; CharDef!1 is stIll in AC3 and 3 1 sub 0 0 sub 1 0 SNR; Nothing to do on zero height (space) characters jmp MagDn sta 0 XH ;let HD = CharDef!1 rshift 8 //number of scanlines to skip ;let y = (Ystart+HD-WindowYmin)*Mag //not really saved ;SetBPtr = DisplayArea + (y*Nwrds) lda 0 C177400; CharDef!1 is stall in AC3 ands 3 0; HD IN AC0 lda 1 Ystart,2 add 1 0 lda 1 WindowYmin sub 1 0 lda 1 Mag jsr @343; Multiply lda 0 Nwrds; y is now in AC1 jsr @343; Multiply lda 0 DisplayArea add 0 1 sta 1 SetBPtr ;Yinc = Nwrds*Mag lda 1 Mag lda 0 Nwrds jsr @343; Multiply sta 1 Yinc ;Ymax = DisplayArea + DsiplaySize-Yinc lda 0 DsiplaySize; Yinc is in AC1 sub 1 0 lda 1 DisplayArea add 1 0 sta 0 Ymax ;OnBits = MaskTable!( Mag+ (BoldFlg? Mag/2, 0) ) lda 0 Mag movzr 0 1 lda 3 BoldFlg,2 mov 3 3 szr add 1 0 lda 3 MaskTable add 0 3 lda 0 0,3 com 0 0 sta 0 OnBits ;let Xpos= (currXposn-WindowXmin)*Mag lda 0 currXposn,2 lda 1 WindowXmin sub 1 0 lda 1 Mag jsr @343; Mul lda 3 C17 com 3 0; put the constant C177760 in AC0 and 1 0 movl# 0 0 SZC add 3 0 cycle 14 sta 0 Xpos ; OnBits,,OffBits = (OnBits,,OffBits) rshift (Xposn) and 1 3 sub 2 2 sub 3 2; leave (-xposn) in AC2 lda 0 OnBits adc 1 1 jsr MaskSh sta 0 OnBits sta 1 OffBits jmp Yloop Nwrds: 36.; **As defined in Sil.defs Yinc: 0 Ymax: 0 Xpos: 0 Xptr: 0 XH: 0 Cnt: 0 wd1: 0 ;now set up outside loop ;for sl = -XH to -1 do Yloop: lda 2 SetBPtr; check for y to small: ifso skip to next scan line lda 3 DisplayArea subo# 3 2 SZC jmp Ydn lda 3 Ymax; check for y to big: ifso done with conversion SGT 3 2 jmp MagDn lda 0 Xpos sta 0 Xptr lda 0 OnBits lda 1 OffBits sta 1 wd1 lda 1 CharDef lda 3 XH add 1 3 lda 1 0,3; lda AC1 with Bits from CharDef!-XH lda 2 Mag jmp NxtBit ;now the end of the loop Ydn: lda 2 Yinc lda 3 SetBPtr add 2 3 sta 3 SetBPtr isz XH; test for all scan lines converted jmp Yloop jmp MagDn ;Now drop into the main bit per scanline loop ;[ //find the next "on"bit in the font and shift the mask bits accordingly ;ShiftCnt = ShiftCnt-Mag ;if FontBits = 0 then break ;let GotBit = (FontBits𘚠) ne 0 ;FontBits = FontBits lshift 1 ;unless GotBit then loop ;] repeat ;MaskSh(onBits,OffBits,ShiftCnt) NxtBit: lda 3 Mag NxtBitL: sub 3 2; assumes initial shift cnt in AC3, inc mov 1,1 SNR; expects Bits to be in AC1 jmp Ydn movzl 1,1 SNC jmp NxtBitL sta 1 SetBMask lda 1 wd1; restore AC1 with word 1 jsr MaskSh Bounds: lda 3 Xptr movl# 3 3 SZC; skip is Xptr is ls 0 jmp BitDn lda 2 Nwrds; return is Xptr gr Nwrds subz 3,2 SBN jmp Ydn com# 1 1 SNR; skip if (word 1 ne 0) & (Xptr eq Nwrds) jmp SetBit movzr 2 2 SNR jmp Ydn SetBit: lda 3 Mag; find the first memory word address to be modified sta 3 Cnt lda 3 SetBPtr lda 2 Xptr add 2,3 SetBitL: lda 2 0,3; get word from screen and 0 2 adc 0 2; result in AC2 and AC0 is left complemented sta 2 0,3 com# 1 1 SNR; skip if wd1 is all zero jmp xitL0 lda 2 1,3; get word from screen and 1 2 adc 1 2; result in AC2 and AC1 is left complemented sta 2 1,3 xitL0: lda 2 Nwrds add 2 3; increment mem pointer by one scan line dsz Cnt jmp SetBitL BitDn: sub 2 2 sta 1 wd1 lda 1 SetBMask jmp NxtBit ;right shift the 32 bit quantity "OnBits,OffBits" ;if OnBits is all zero, then swap words and increment Xptr ;NOTE the content of OnBits,OffBits are to be or'd into the bit map, ;and for convenience of the "OR" algorithm are complements of the bits to be or'd. MaskSh: sta 3 Cnt; Cnt is a handy unused register at this point mov 2 2 SNR; AC2 contains toe quantity to be shifted jmp@ Cnt; skip if we don't have any count shiftL: movor 0,0; now shift the bit pattern movr 1,1 com 0,3 SZR; swap words and increment Xptr if all bits are in OffBits jmp ShiftDn mov 1 0 com 3 1 isz Xptr ShiftDn: inc 2,2 SZR; test for all bits shifted jmp shiftL jmp@ Cnt .end ;(0,4896)