.titl SpruceBandMl ; BandEnter(band,len) ; Must be called to make a new band entry official. ; New band information has been placed in the table beginning at BandFree. ; BandAvail is set to allow it to overflow by one maximum-sized entry. ; See SpruceBand for algorithm description -- this code links to microcode. ; RowRotate(inBuf, outBuf, wordsPerRow) rotates Alto resolution bit map rows ; SetupShowFonts(specs) ; SetupShowChars(specs, numChars, streamFsp) feeds parameters to show microcode ; code = ShowChars(lvC, lvBand) ;OrbitCharSize(width,height) returns number of words for char: ; ((width*height+15)/16+2+1)&(-2) .bext BandEnter .bext BandFree, BandAvail, BandTable, onlyOnCopy, BandFlush, CopyTable .bext CurS, CurB, fspn, fspo, nVisibleBands, bc .ent RowRotate, SetupShowChars, ShowChars, SetupShowFonts, OrbitCharSize .ent FlushChars .srel OrbitCharSize: .orbitCharSize BandEnter: .BandEnter RowRotate: .RowRotate ShowChars: .ShowChars SetupShowChars: .SetupShowChars SetupShowFonts: .SetupShowFonts FlushChars: .FlushChars .nrel savedPC=1 temp=2 extraArguments=3 ;; ************** r... indices here match those in microcode (ShowCharsMc), and the sequences ;; ************** of register references depend on the order of static placement in SprintStatics.bj! LOADR=71000 ; R←@AC0, AC0←AC0+1 STORER =70000 ; @AC0←R, AC0←AC0+1 JMPRAM = 61010 rVis = 660 ; R66, nVisibleBands rBTable = 700 ; R70, BandTable rCTable = 520 ; R52, CopyTable rUses = 640 ; R64, ICCUses rOffset = 630 ; R63, ICCOffset rBc = 620 ; R62, bcM1 rEc = 610 ; R61, ec rWidth = 670 ; R67, WidthPointer rSpn = 160 ; R16, fspn rSpo = 150 ; R15, fspo rCop = 650 ; R65, OnlyOnCopy rS0 = 600 ; R60, CurS0 rS1 = 570 ; R57, CurS1 rB0 = 560 ; R56, CurB0 rB1 = 550 ; R55, CurB1 rFree = 540 ; R54, BandFree rPData=540 ; R54, in FlushChars rAvail = 530 ; R53, BandAvail rCt = 460 ; R46, ct rC = 470 ; R52, c rNumData=470 ; R52, in FlushChars rBand = 510 ; R51, band rOutAddr=510 ; R51, in FlushChars rByteIdx = 450 ; R45, byte index for stream access rBase = 440 ; R44, address of current data word or so rData = 430 ; R43, current data word rP = 410 ; R41, loaded externally in FlushChars rLen=420 ; R42, entryLen, in BandEnter rLeftCt = 420 ; R42, in FlushChars ; ***** indices into the fsp portion of a stream structure -- see FSP ****** CharPtr = 0 WordPtr = 1 Count = 2 Dirty = 3 ; BandEnter(band, len) ; BandTable, CopyTable already loaded into appropriate regs. .BandEnter: sta 0 1 2 sta 1 2 2 inc 2 0 LOADR+rBand LOADR+rLen lda 0, .only LOADR+rCop lda 0, .bTable LOADR+rBTable LOADR+rCTable lda 0 .BandFree LOADR+rFree LOADR+rAvail lda 1 RamBandEnter JMPRAM; do the BandEnter mov 0 1 lda 0 .BandFree STORER+rFree STORER+rAvail snz 1 1 jmp 1 3 inc 3, 3 sta 3, save3 jsrii .bFlush ;BandFlush() 0 jmp @save3 .SetupShowFonts: ; values that remain permanent while font is loaded ; (except while doing dots) lda 0,.vis LOADR+rVis lda 0, .bTable LOADR+rBTable LOADR+rCTable LOADR+rUses LOADR+rOffset lda 1 @.bc dsz @.bc mov# 0, 0 LOADR+rBc sta 1 @.bc LOADR+rEc LOADR+rWidth jmp 1,3 .SetupShowChars: ;0 is nChars, 1 => FSP portion of stream sta 3, 2, 2 ; not the normal roles -- indices used explicitly to exhibit relationships sta 0, 1,2 ; used below (see lines marked with ** and subsequent similar ones) sta 1, 3, 2 ; ~~ MUST document this stuff. lda 0, .only LOADR+rCop sub 0,0 sta 0, @.fspn sta 0, @.fspo lda 0, .fspn LOADR+rSpn LOADR+rSpo lda 0, @.CurS LOADR+rS0 LOADR+rS1 lda 0, @.CurB LOADR+rB0 LOADR+rB1 inc 2 0; ** 0 is lv 1,2 ** LOADR+rCt sub 0 0 lda 1 @3, 2 ;fsp.charPtr sn 1 1 mknil 0 0 sta 0 1,2 ;0 if charPtr of stream was non-zero, -1 otherwise -> byteIdx inc 2 0 ; ** LOADR+rByteIdx; fsp.wordPtr lda 3 3, 2 ;fsp lda 0 1 3 ;address of data, more or less lda 1 1 2 ; previously derived byteIdx determines where initial data word will be sub 1, 0 sta 0 1,2 LOADR+rData ; AC0 here is address of 1st data word inc 2 0; ** ; AC0 here is address of address of 1st data word, to be put in base register LOADR+rBase lda 3 2, 2 jmp 1 3 .bFree: .BandFree: BandFree .bAvail: BandAvail .bTable: BandTable .cTable: CopyTable .only: onlyOnCopy .bFlush: BandFlush .vis: nVisibleBands .bc: bc .CurS: CurS .CurB: CurB .fspn: fspn .fspo: fspo save0: 0 save1: 0 save2: 0 save3: 0 RamRowRotate: 23 RamFlushChars: 24 RamShowChars: 25 RamBandEnter: 30 .ShowChars: sta 3, save3 sta 2, save2 ; ShowChars microcode uses all Acs sta 0, save0 again: lda 0 .BandFree LOADR+rFree LOADR+rAvail lda 1,RamShowChars ; ShowChars starts at RAM 25 JMPRAM lda 2, save2 mov 0 1 ; return code lda 0 .BandFree STORER+rFree STORER+rAvail jsr postT ; ****** These order of these instructions must remain compatible with the MU... codes in ShowCharMc table: jmp done ; 0 result -- all done jmp range jmp range ; range or other errors jmp full ; buffer full ; ****** postT: add 1 3 jmp 0 3 ;dispatch full: jsrii .bFlush 0 jmp again done: lda 0 .fspn STORER+rSpn STORER+rSpo lda 0 @.CurS STORER+rS0 STORER+rS1 lda 0 @.CurB STORER+rB0 STORER+rB1 jmp quit range: lda 0 save0 ;address of variable to hold most recently considered char. STORER+rC quit: lda 3,save3 mov 1 0 ;result returned from microcode jmp 1,3 ; FlushChars ; FlushChars(lv p, fsP) ; p, nextP are contiguous .FlushChars: inc 3,3 sta 3, savedPC, 2 sta 0, save0; lv (p, nextP) LOADR+rP inc 1 0; word 0 is (next out address)-1, word 1 is -(#left+1) sta 0, save1; fsp stream information LOADR+rOutAddr; WordPtr LOADR+rLeftCt; Count lda 1 RamFlushChars ; FlushChars code in RAM JMPRAM mov 0,1 ; return code, save lda 0, save0 STORER+rPData ; current version of p STORER+rP ; next version of p, not always derivable from p STORER+rNumData; (#words in previous p)-1 lda 0 save1 STORER+rOutAddr STORER+rLeftCt mov 0,3 ; fsp.Dirty sta 3, 0, 3 ; denote current output page dirty mov 1,0 jmp @savedPC, 2 ; Other ml routines and mu linkages .orbitCharSize: sta 3 savedPC,2 mov 2,3 mov 0,2 lda 0,dorb mul ; ac0,1 ← height*width+15+3*16 movr 0,0 movr 1,1 movr 0,0 movr 1,1 movr 0,0 movr 1,1 movr 0,0 movr 1,1 mov 1,0 lda 1,cm2 and 1,0 ; make even number mov 3,2 lda 3 savedPC,2 jmp 1,3 dorb: 15.+(3*16.) cm2: 177776 .RowRotate: sta 3,savedPC,2 sta 2,save2 ; never reentered! lda 3,extraArguments,2 ;wordsPerRow mov 1,2 ; outBuf AC0 is inBuf lda 1,RamRowRotate ; ROWROT starts at RAM 23 toram: 61010 ;JmpRam(23) lda 2,save2 lda 3,savedPC,2 jmp 1,3 ; Runtime Initialization (for GetFrame, return) ;; DCS, September 27, 1977 2:57 PM, created ;; October 18, 1978 12:23 PM, moved in a lot of band-related stuff from spruceml ;; October 19, 1978 8:55 AM, modified ShowChars interfaces to use LOADR, STORER ;; October 19, 1978 10:41 PM, lotsa bugs ;; October 23, 1978 7:13 AM, add FlushChars ;; October 24, 1978 9:58 AM, onlyOnCopy cleanups, mods -- BandEnter a lot simpler ;; .end