; WriteR270.asm -- a collection of assembly code display procedures for xm machine
; by Keith Knox last modified September 18, 1979
; by Paul Lam last modified March 2, 1981


; write -- procedure to write on the display

.BEXTwriteR270
.BEXTBitBlt

.BEXTZ MaxStringHeight, HardCopy, ItalicsBuff, Mag, WindowYmin, WindowXmin
.BEXTZ SavedAC2,CharDef ,CurrentYpos
.BEXTZ DisplayArea, SetBPtr, OnBits, OffBits, SetBMask, MaskTable


.SREL
writeR270:
WRITE3

; write(BBTable, string, font, maxwidth, maxheight,hcwidthvec,rot,magflag,magarea, Yo, type)
; uses BitBlt to write a horizontal string from AL fonts
; It may be possible that this code and the BitBlt code are on separate overlays.
; If so, this procedure must have a stack so that its overlay will not be freed
; when the BitBlt overlay is read into memory.

; BitBlt table should (start on an even address and) be initialized as follows:
; 0--function
// source=block, dest=alt or norm bank, fn=replace,paint,invert,erase
; 1--unused
; 2--dcb!2+TY*((dcb!1)Ź)
; 3--((dcb!1)Ź)
; 4--LX
// updated with width of each character
; 5--0
; 6--0
; 7--0
; 8--0
; 9--1
; 10--0
; 11--0

; if xw=font+char+font!char then BBTable is changed as follows:
; 4--BBTable!4+((xw!0)/2 or 16)
; 5--(xw!1) rshift 8
; 6--(xw!0)/2 or 16
; 7--xw!1 & #377
; 8--xw-(xw!1 & #377)

; Displacements from BBTable
DestBCA = 2
DestBMR = 3
lx=4
disp=5
width=6
height=7
bitmap=8.

; Displacements from stack pointer
string=5
font=6
maxwidth=7
maxheight=8.
hcwidthvec=9.
rot=10.
MagFlag = 11.
MagArea = 12.
YScanstart = 13.
Type=14.
Xstart = 15.
Ystart = 16.
ALHeight = 17.
currXposn = 18.
Lastlx=19.
Displaywidth=20.
BoldFlg=21.


.NREL
Home:
; now time to go home
LDA 2 SaveAC2
LDA 0 RotatedHeight
JSR @366

WRITE3:
STA 3 1 2
JSR @370
30
JSR @367; number arguments is stored in register 0

STA 2 SaveAC2; don’t use BBTable!1 because BitBlt(BBTable) may use it
MOV 2 3
LDA 2 4 2; get BBTable address
LDA 1 lx 2
STA 1 Xstart 3; init xstart
LDA 1 DestBCA 2
STA 1 Ystart 3
SUB 1 1
STA 1 MicaPosn; init MicaPosn
STA 1 ScHeight; init ScHeight
STA 1 RotatedHeight; init RotatedHeight
LDA 2 SaveAC2

lda 0 DisplaySize;
lda 1 DisplayArea
add 0 1
sta 1 MaxDestBCA

LDA 1 c377; initialize the character mask
STA 1 mask
LDA 0 hcwidthvec 2
STA 0 WidthVector

LDA 0 @string 2; initialize the character mask
MOVS 0 0
AND 1 0
SNZ 0 0
JMP Home; if string is emptythen go home
STA 0 charsdone

toploop:
; loop over the # of chars in the string

; get a char and leave it in AC0
LDA 2 SaveAC2; restore stack pointer
LDA 3 string 2; get address of word in string
LDA 0 0 3; get word in string
LDA 1 mask
AND 1 0; mask out the character
SODD 1 1
MOVS 0 0; if necessary, right justify character
INC 3 3
SKEVEN 1 1
STA 3 string 2; if necessary, increment string pointer
COM 1 1
STA 1 mask; switch mask between left and right byte
STA 0 SaveHChar; save char code for hardcopy width calculation

writechar:
; write out the character in AC0
; get the character descriptor
STA 0 SaveChar
LDA 2 SaveAC2; restore stack pointer
LDA 1 font 2; get font pointer
lda 0 c1
sub 0 1
#61025; #61025; xmlda -- ac0 ← @ac1
lda 1 c377
and 1 0
lda 1 c1
add 1 0
sta 0 ALHeight 2; init font height
sta 0 MaxStringHeight; update string height
LDA 1 font 2; get font pointer
lda 0 SaveChar
add 0 1
#61025; #61025; xmlda -- ac0 ← @ac1
add 0 1
#61025; #61025; xmlda -- ac0 ← @ac1; AC0 now contains xw!0
sta 0 xw0; ac0 contains xw!0; save it
sta 1 CharBitmapPtr; save character bitmap pointer
inc 1 1
#61025; #61025; xmlda -- ac0 ← @ac1; AC1 now contains xw!1
sta 0 xw1; AC0 = xw!1
LDA 1 c377
AND 0 1
LDA 3 CharBitmapPtr; get character bitmap pointer
SUB 1 3; ac3 has font pointer
LDA 2 4 2; get the BBTable address
STA 3 bitmap 2; bitmap=xw-(xw!1 & #377)

; fill in the height, width, displacement and character bitmap address
LDA 1 c377
COM 1 1
ANDS 0 1; AC0 = xw!1
STA 1 disp 2; displacement = xw!1 rshift 8
ADD 1 0
LDA 1 c377
AND 0 1
STA 1 height 2; height = xw!1 & #377 + disp
JMP SoftDisplay

BitBltProc:
BitBlt
charsdone: 0
mask:
377
CharBitmapPtr: 0
xw0: 0
xw1: 0
c377:
377
c20:
20
SaveChar: 0
SaveHChar: 0
WidthVector: 0
DisplaySize:27432.;**As defined by Sil.defs (Nwrds*ScreenYmax)
MaxDestBCA:
0;
C50: 50.
C1778:
1778.
MicaPosn: 0
ScHeight: 0
HcWidth: 0
SaveAC2: 0
c1:
1
c4:
4
RotatedHeight:
0


SoftDisplay:
; check the width, we may want to quit now

LDA 3 SaveAC2; restore stack pointer
STA 3 StackPtr
LDA 1 maxwidth 3; don’t go beyond this limit
SNZ 1 1; see when maxwidth becomes zero
JMP alldone; no more to do
LDA 0 xw0
SODD 0 0
JMP SD1
LDA 1 RotatedHeight
LDA 0 height 2
ADD 1 0
LDA 1 maxwidth 3; don’t go beyond this limit
SUB 0 1; decrement the maxwidth limit
SN 1 1; is this character too wide?
JMP .+6
SUB 1 1; make maxwidth zero
STA 1 maxwidth 3; maxwidth is zero now
inc 1 1
inc 1 1
STA 1 height 2; new height
SD1:
LDA 1 ALHeight 3; get the al font height
LDA 0 disp 2; number of lines to skip
SUB 0 1
STA 1 width 2; store width in BBTable
; check for width greater then 16
LDA 0 c20
SUB 0 1
SN 1 1; skip if width less then 16
STA 0 width 2
; check for large fonts
LDA 1 c20
LDA 0 xw0
SODD 0 0
STA 1 width 2
; check the height, we may want to limit this character
LDA 0 width 2;
LDA 1 maxheight 3; get limiting height
SGT 1 0; see if displacement is equal to maxheight
MOV 1 0; height becomes maxheight
STA 0 width 2;

; now actually put the character bitmap in the display using BitBlt
SUB 1 1
MOV 2 0
gotobbt:
LDA 2 SaveAC2; restore stack pointer
JSRII BitBltProc; BitBlt(BBTable)
1
LDA 2 4 2; get BBTable address

; see if there are extensions
nextchar:
JSR UpdateWidth
donext:
LDA 1 xw0; if odd then no extension
MOVZR 1 0; AC0 = pseudocharacter
SODD 1 1
JMP writechar; there is an extension, go back and try again

; check if done with string
DSZ charsdone
JMP toploop; end of the loop

alldone:
; now time to go home
LDA 2 SaveAC2
LDA 0 RotatedHeight
JSR @366

; 270 degrees rotation, therefore advance in the y direction
UpdateWidth:
STA 3 Rrtn; save return addr
; check for extension
LDA 1 xw0
MOVZR 1 0
SODD 1 1
JMP ExtensionCal; there is an extension, go back & display the rest
LDA 1 ScHeight; do soft copy width
LDA 0 height 2
MOV 0 0 snr
LDA 0 c4; space
ADD 0 1
STA 1 ScHeight
JSR WriteWidth ; ac1 has the rotated width
; check if hardcopy
JSR HardCopyCal; always cal the hardcopy width
LDA 0 HardCopy
MOV 0 0 SNR
JMP @Rrtn; soft copy ; just return
LDA 1 HcWidth; init to hardcopy width
JSR WriteWidth ; ac1 has the rotated width
JMP @Rrtn

ExtensionCal:
;
LDA 0 lx 2
LDA 1 c20
ADD 1 0
STA 0 lx 2
JMP @Rrtn

WriteWidth:
STA 3 Wrtn
STA 1 RotatedHeight
LDA 3 SaveAC2; restore stack pointer
LDA 0 Xstart 3; always restore lx in case changed by extended char image
STA 0 lx 2
LDA 0 Ystart 3
; ac0 = ysatr; ac1 = width/height
LDA 2 Nwrds
MUL; 1*2 + 0 -> 1
LDA 2 SaveAC2; restore stack pointer
LDA 2 4 2; get BBTable address
STA 1 DestBCA 2
JMP @Wrtn

;MicaPosn = MicaPosn + WidthPointer!char
;Xposn = Xstart + MicvaPosn*1778/50

HardCopyCal:
STA 3 Hrtn
STA 2 tempac2
LDA 1 WidthVector
LDA 0 SaveHChar; get Char code
ADD 0 1
#61025; #61025; xmlda -- ac0 ← @ac1
LDA 1 MicaPosn
ADD 0 1
STA 1 MicaPosn;MicaPosn 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
STA 1 HcWidth
LDA 2 tempac2
JMP @Hrtn

Rrtn: 0
Wrtn: 0
Hrtn: 0
tempac2: 0
StackPtr: 0
Nwrds: 36.

.END