-- ScanImpl.mesa edit by McGregor December 9, 1980 11:06 AM DIRECTORY JasmineDefs: FROM "JasmineDefs", GraphicsDefs: FROM "GraphicsDefs", HalftoneDefs: FROM "HalftoneDefs", ImageDefs: FROM "ImageDefs", InlineDefs: FROM "InlineDefs", IODefs: FROM "IODefs", Mopcodes: FROM "Mopcodes", OsStaticDefs: FROM "OsStaticDefs", StreamDefs: FROM "StreamDefs", StringDefs: FROM "StringDefs"; ScanImpl: PROGRAM IMPORTS GraphicsDefs, HalftoneDefs, ImageDefs, InlineDefs, IODefs, JasmineDefs, StreamDefs, StringDefs = BEGIN OPEN JasmineDefs; Black: CARDINAL _ 0; White: CARDINAL _ 255; XStart: CARDINAL _ 0; XLen: CARDINAL _ 1024; YStart: CARDINAL _ 177777B; YLen: CARDINAL _ 1024; ScanLen: CARDINAL _ 608; DCBHead: POINTER TO CARDINAL = LOOPHOLE[420B]; nScanLines: CARDINAL _ 808; keys: StreamDefs.StreamHandle _ IODefs.GetInputStream[]; CursorY: POINTER TO CARDINAL = LOOPHOLE[425B]; ControllerOn: BOOLEAN _ TRUE; RamVal: TYPE = MACHINE DEPENDENT RECORD [ blank: [0..17B], offset: [0..77B], gain: [0..77B] ]; AISHeader: TYPE = MACHINE DEPENDENT RECORD [ password: CARDINAL _ 102252B, headerLen: CARDINAL _ 1024, partType: [0..77B] _ 1, partLen: [0..1777B] _ 10, scanCount: CARDINAL, scanLength: CARDINAL, scanDir: CARDINAL _ 3, samplesPerPixel: CARDINAL _ 1, codingType: CARDINAL _ 1, bitsPerSample: CARDINAL _ 8, wordsPerScanline: CARDINAL, scanlinesPerBlock: CARDINAL _ 177777B, padPerBlock: CARDINAL _ 177777B, nextPartType: CARDINAL _ 0 ]; PressCommands: TYPE = MACHINE DEPENDENT RECORD [ SetCoding: [0..377B] _ 1, code: [0..377B] _ 8, dots: CARDINAL, lines: CARDINAL, SetMode: [0..377B] _ 2, mode: [0..377B] _ 3, SetSize: CARDINAL _ 2, width: CARDINAL, height: CARDINAL, SetSamplingProperties: CARDINAL _ 6, n: CARDINAL _ 7, SSPInputIntensity: CARDINAL _ 0, min: CARDINAL, max: CARDINAL, SSPScreen: CARDINAL _ 2, angle: CARDINAL _ 45, amplitude: CARDINAL _ 100, frequency: CARDINAL, SetWindow: CARDINAL _ 1, pd: CARDINAL _ 0, dd: CARDINAL, pl: CARDINAL _ 0, dl: CARDINAL, DotsFollow: CARDINAL _ 3 ]; PressTrailer: TYPE = MACHINE DEPENDENT RECORD [ zero: CARDINAL _ 0, SetX: [0..377B] _ 356B, xHigh: [0..377B] _ (2540/2)/256, xLow: [0..377B] _ (2540/2) MOD 256, SetY: [0..377B] _ 357B, y: CARDINAL _ 2540/2, nop: [0..377B] _ 377B, ShowDots: [0..377B] _ 374B, nDotsWordsHigh: CARDINAL, nDotsWordsLow: CARDINAL, typeFontset: CARDINAL _ 0, beginByteHigh: CARDINAL _ 0, beginByte: CARDINAL _ 2*(1024-SIZE[PressCommands]), nEntityWordsHigh: CARDINAL, nEntityWordsLow: CARDINAL, Xe: CARDINAL _ 0, Ye: CARDINAL _ 0, Left: CARDINAL _ 0, Bottom: CARDINAL _ 0, Width: CARDINAL _ 0, Height: CARDINAL _ 0, TrailerLen: CARDINAL _ 18 ]; PressPartDir: TYPE = MACHINE DEPENDENT RECORD [ dataPage: CARDINAL _ 0, dataStart: CARDINAL _ 0, dataRecords: CARDINAL, dataPadLen: CARDINAL, fontPage: CARDINAL _ 1, fontStart: CARDINAL, fontRecords: CARDINAL _ 1, fontPadLen: CARDINAL _ 255 ]; PressDocDirHeader: TYPE = MACHINE DEPENDENT RECORD [ password: CARDINAL _ 27183, nRecords: CARDINAL, nParts: CARDINAL _ 2, partDirStart: CARDINAL, partDirLen: CARDINAL _ 1 ]; Main: PROCEDURE = BEGIN Screen: POINTER TO GraphicsDefs.Bitmap; nextDCB: POINTER TO ARRAY[0..3] OF CARDINAL _ LOOPHOLE[DCBHead^]; DCBtop: POINTER _ nextDCB; UNTIL nextDCB[0] = 0 DO nScanLines _ nScanLines - nextDCB[3]*2; nextDCB _ LOOPHOLE[nextDCB[0]]; ENDLOOP; nScanLines _ nScanLines - nextDCB[3]*2; GraphicsDefs.SetDefaultBitmap[608,nScanLines]; Screen _ GraphicsDefs.TurnOnGraphics[]; nextDCB _ LOOPHOLE[DCBHead^]; nextDCB[0] _ LOOPHOLE[DCBtop]; JasmineInit[]; DO --main loop JasmineMotorOff[]; IODefs.WriteLine[""]; SELECT IODefs.ReadChar[] FROM '? => BEGIN IODefs.WriteString[" Black: "];IODefs.WriteDecimal[Black]; IODefs.WriteString[" White: "];IODefs.WriteDecimal[White]; IODefs.WriteString[" XStart: "];IODefs.WriteDecimal[XStart]; IODefs.WriteString[" XLen: "];IODefs.WriteDecimal[XLen]; IODefs.WriteString[" YStart: "];IODefs.WriteDecimal[YStart]; IODefs.WriteString[" YLen: "];IODefs.WriteDecimal[YLen]; END; '! => BEGIN IODefs.WriteString["Controller "]; ControllerOn _ NOT ControllerOn; IF ControllerOn THEN BEGIN JasmineControllerOn[];IODefs.WriteString["ON"];END ELSE BEGIN JasmineControllerOff[];IODefs.WriteString["OFF"];END; END; 'b => BEGIN IODefs.WriteString["Black: "];Black_IODefs.ReadDecimal[];END; 'c => BEGIN IODefs.WriteLine["Calibrate: Insert sheet of white paper"]; JasmineEject[]; --first, eject old page IODefs.WriteString[" Press any key when ready"]; [] _ IODefs.ReadChar[]; JasmineNewPage[14]; JasmineCalibrate[]; JasmineEject[]; --eject this page END; 'd => BEGIN IODefs.WriteString["Delay setting: "]; JasmineSetDelay[IODefs.ReadDecimal[]]; END; 'e => BEGIN IODefs.WriteString["Erase"]; GraphicsDefs.EraseArea[0,0,ScanLen,700]; END; 'f => BEGIN IODefs.WriteString["Forward nSteps: "]; JasmineStep[IODefs.ReadDecimal[],TRUE]; END; 'h => BEGIN IODefs.WriteString["Halftone"]; DoHalftone[]; END; 'i => BEGIN r: RamVal _ [0,64-10,0]; a: ARRAY [0..1024) OF RamVal _ ALL[r]; IODefs.WriteString["Initialize RAMs"]; JasmineLoadRam[LOOPHOLE[@a]]; END; 'l => BEGIN IODefs.WriteString["Length of scan: "]; ScanLen_IODefs.ReadDecimal[]; END; 'n => BEGIN IODefs.WriteLine["New Page"]; JasmineEject[]; --first, eject old page IODefs.WriteString[" Press any key when ready"]; [] _ IODefs.ReadChar[]; JasmineNewPage[14]; XStart_0;XLen_1024;YStart_0;YLen_1400; JasmineSetWindow[XStart,XLen,YStart,YLen]; END; 'o => BEGIN savedDCB: CARDINAL _ DCBHead^; fileName: STRING _ [40]; IODefs.WriteString["Output file name: "]; IODefs.ReadID[fileName]; DCBHead^_ 0; WriteFile[fileName]; DCBHead^_ savedDCB; END; 'q => BEGIN IODefs.WriteString["Quit"]; JasmineEject[]; JasmineControllerOff[]; ImageDefs.StopMesa[]; END; 'r => BEGIN IODefs.WriteString["Reverse nSteps: "]; JasmineStep[IODefs.ReadDecimal[],FALSE]; END; 's => BEGIN IODefs.WriteString["Skip count: "]; JasmineSetResolution[IODefs.ReadDecimal[]]; END; 't => BEGIN IODefs.WriteString["Time for integration: "]; JasmineSetTime[IODefs.ReadDecimal[]]; END; 'w => BEGIN IODefs.WriteString["White: "];White_IODefs.ReadDecimal[];END; 'x => BEGIN IODefs.WriteString["X"]; SELECT IODefs.ReadChar[] FROM 'l => BEGIN IODefs.WriteString["Len: "]; XLen_MIN[IODefs.ReadDecimal[],1024-XStart]; END; 's => BEGIN IODefs.WriteString["Start: "];XStart_IODefs.ReadDecimal[]; XLen_MIN[XLen,1024-XStart]; END; ENDCASE => IODefs.WriteString["???"]; END; 'y => BEGIN IODefs.WriteString["Y"]; SELECT IODefs.ReadChar[] FROM 'l => BEGIN IODefs.WriteString["Len: "];YLen_IODefs.ReadDecimal[]; END; 's => BEGIN IODefs.WriteString["Start: "];YStart_IODefs.ReadDecimal[]; END; ENDCASE => IODefs.WriteString["???"]; END; 'z => BEGIN Buttons: TYPE = MACHINE DEPENDENT RECORD [ KeyPadAndGarbage: [0..10000B), Red: [0..1], Blue: [0..1], Yellow: [0..1] ]; MouseButtons: POINTER TO Buttons = LOOPHOLE[177030B]; CursorX: POINTER TO CARDINAL = LOOPHOLE[426B]; CursorY: POINTER TO CARDINAL = LOOPHOLE[427B]; x,y: CARDINAL; dx,dy: INTEGER _ 0; IODefs.WriteString["Zoom"]; UNTIL MouseButtons.Red = 0 DO ENDLOOP; x _ CursorX^;y _ CursorY^; DO WHILE MouseButtons.Red = 0 DO XorBox[x,y,dx,dy]; dx _ CursorX^ - x;dy _ CursorY^ - y; XorBox[x,y,dx,dy]; ENDLOOP; IF dx < 0 THEN BEGIN x _ x+dx;dx _ ABS[dx];END; IF dy < 0 THEN BEGIN y _ y+dy;dy _ ABS[dy];END; WHILE MouseButtons.Yellow = 0 DO --move origin XorBox[x,y,dx,dy]; x _ CursorX^;y _ CursorY^; XorBox[x,y,dx,dy]; ENDLOOP; IF MouseButtons.Blue = 0 THEN EXIT; ENDLOOP; XorBox[x,y,dx,dy]; XStart _ XStart + MulDiv[x,XLen,ScanLen]; YStart _ YStart + MulDiv[y,XLen,ScanLen]; YLen _ MulDiv[dy,XLen,ScanLen]; XLen _ MulDiv[dx,XLen,ScanLen]; DoHalftone[]; END; ENDCASE; ENDLOOP; --main loop on characters END; WriteFile: PROCEDURE [fileName: STRING] = BEGIN OPEN StreamDefs; jx: CARDINAL _ JasmineCoord[XLen]; odd: CARDINAL _ jx MOD 2; ais: AISHeader _ [ scanCount: JasmineCoord[YLen],scanLength: jx+odd, wordsPerScanline: (jx+1)/2 ]; micaWidth: CARDINAL _ MulDiv[ScanLen,2540,100]; press: PressCommands _ [ dots: jx+odd,lines: JasmineCoord[YLen], width: micaWidth,height: MulDiv[micaWidth,YLen,XLen], min: --Black--0, max: --White--255, frequency: MIN[85,MulDiv[jx,100,ScanLen]], dd: jx,dl: JasmineCoord[YLen] ]; nDotsWords: LONG CARDINAL _ LONG[(jx+1)/2]*JasmineCoord[YLen]; nEntityWords: LONG CARDINAL _ nDotsWords+18; trailer: PressTrailer _ [ nDotsWordsHigh: InlineDefs.HighHalf[nDotsWords], nDotsWordsLow: InlineDefs.LowHalf[nDotsWords], nEntityWordsHigh: InlineDefs.HighHalf[nEntityWords], nEntityWordsLow: InlineDefs.LowHalf[nEntityWords] ]; padLen: CARDINAL _ 377B-(InlineDefs.LowHalf[nEntityWords] MOD 256); recordLen: CARDINAL _ (InlineDefs.HighHalf[nEntityWords] MOD 256)*256 + (InlineDefs.LowHalf[nEntityWords]/256) + 4 + 1;--4 for 1024 hdr partdir: PressPartDir _ [ dataRecords: recordLen,dataPadLen: padLen,fontStart: recordLen]; docdirhdr: PressDocDirHeader _ [ nRecords: recordLen+3,--font,part,doc partDirStart: recordLen+1 ]; file: StreamHandle _ NewWordStream[fileName,Write+Append]; scanHead: POINTER TO ScanHead; x, y: CARDINAL; bcplFileName: StringDefs.BcplSTRING; sl: POINTER TO PACKED ARRAY OF [0..377B]; range:CARDINAL_White-Black; JasmineSetWindow[XStart,XLen,YStart,YLen]; scanHead _ JasmineScanInit[]; [] _ WriteBlock[file,@ais,1024-SIZE[PressCommands]]; [] _ WriteBlock[file,@press,SIZE[PressCommands]]; FOR y IN [1..JasmineCoord[YLen]] DO sl _ JasmineReadLine[scanHead]; IF odd = 1 THEN sl[jx] _ sl[jx-1]; IF White#255 OR Black#0 THEN FOR x IN [1..jx] DO -- save user threshhold values sl[x]_((MAX[Black,MIN[sl[x],White]]-Black)*255)/range; ENDLOOP; [] _ WriteBlock[file,sl,(jx+1)/2]; CursorY^ _ MulDiv[y,800,JasmineCoord[YLen]]; ENDLOOP; JasmineScanClose[scanHead]; [] _ WriteBlock[file,@trailer,SIZE[PressTrailer]+padLen]; --nil font part file.put[file,0]; [] _ WriteBlock[file,NIL,255]; --part dir [] _ WriteBlock[file,@partdir,256]; --doc dir [] _ WriteBlock[file,@docdirhdr,SIZE[PressDocDirHeader]]; THROUGH[SIZE[PressDocDirHeader]..177B] DO file.put[file,-1];ENDLOOP; StringDefs.MesaToBcplString[fileName,@bcplFileName]; [] _ WriteBlock[file,@bcplFileName,26]; [] _ WriteBlock[file,OsStaticDefs.OsStatics.UserName,16]; [] _ WriteBlock[file,NIL,256-252B]; file.destroy[file]; END; DoHalftone: PROCEDURE = BEGIN OPEN HalftoneDefs; scanHead: POINTER TO ScanHead; depth: CARDINAL _ 1; JasmineSetWindow[XStart,XLen,YStart,YLen]; scanHead _ JasmineScanInit[]; InitHalftone[0,0,JasmineCoord[XLen],ScanLen,Black,White]; -- blackDCB!3=1 -- unless DisplayOn do @#420=blackDCB THROUGH [0..JasmineCoord[YLen]) DO IF NOT keys.endof[keys] THEN EXIT; BEGIN depth _ depth + PrintHalftoneLine[JasmineReadLine[scanHead]]; -- blackDCB!3=(depth+1)/2 IF depth >= nScanLines-10 THEN EXIT; --WRONG!!! END; ENDLOOP; JasmineScanClose[scanHead]; -- @#420=dcb END; MulDiv: PROCEDURE [a,b,c: CARDINAL] RETURNS [CARDINAL] = BEGIN RETURN[InlineDefs.LongDiv[InlineDefs.LongMult[a,b],c]]; END; XorBox: PROCEDURE[x,y,dx,dy: CARDINAL] = BEGIN GraphicsDefs.XorArea[x,y,x+dx,y]; GraphicsDefs.XorArea[x+dx,y,x+dx,y+dy]; GraphicsDefs.XorArea[x+dx,y+dy,x,y+dy]; GraphicsDefs.XorArea[x,y+dy,x,y]; END; Main[]; END. (635)\f1 3b8B1421f0 25f1 1676b4B5050b9B107f0 2f1 70f0 2f1 118f0 2f1 150f0 2f1 21f0 2f1 62f0 2f1 1187f0 2f1 67i27I95f0 2f1 611b10B489b10B