CMM2 sliderule

Compatible with:
DOS Maximite CMM MM150 MM170 MM+ MMX Picromite ArmiteL4 Armite F4 ArmiteH7 Picomite CMM2

Description:
This BAS program brings back memories of pre-calculator university days.
You need to edit the mouse_port to match your installation.

 

 'TassyJim December 2020, January 2021
 '
 'simple Mannheim type slide rule
 ' translated for a post on the LIberty Basic forum by tsh73
 'If you need instructions on operating slide rule, you can check
 'https://www.sliderulemuseum.com/
 '
 OPTION EXPLICIT
 OPTION DEFAULT FLOAT
 DIM INTEGER mouse_port = 0 ' use -1 for no mouse else 0-3 for the corresponding port
 DIM WW = MM.HRES
 DIM x0=1
 DIM x1=10
 DIM n = 1000
 DIM h0 = (x1)/n
 DIM firstXX=30
 DIM SCALE = (WW - 2*firstXX)/LOG(x1)
 
 'vertical scale positions in pixels
 CONST Tedge = 30
 CONST Lline  = Tedge + 35
 CONST Kline  = Lline + 35
 CONST ABline = Kline + 35
 CONST CDline = ABline+ 70
 CONST Sline  = CDline+ 70
 CONST Tline  = Sline + 35
 CONST Ledge  = Tline + 10
 
 DIM x,i,h,d,xx, lastxx, dd, quit, kp,sp, nudge
 DIM oldFirstXX, k, slidepos, oldpos, cursorpos, oldcursorpos
 DIM mx, my, ms, mc, mlb, oldmx, oldlmb
 CONST bg1 = RGB(255,255,128)
 CONST bg2 = RGB(WHITE)
 CONST gra = RGB(32,32,32)
 
 MODE 1,8,RGB(BLACK)
 CLS
 PAGE WRITE 2
 CLS
 IF mouse_port >= 0 THEN
   CONTROLLER MOUSE OPEN mouse_port
   GUI CURSOR ON 1,MM.HRES/2,MM.VRES/2,RGB(RED)
 ENDIF
 BOX 10,Tedge+5,WW-10,Kline-Tedge,1,bg1,bg1
 BOX 10,Kline+5,WW-10,Sline-Kline,1,bg2,bg2
 BOX 10,Sline-30,WW-10,Ledge-Sline+35,1,bg1,bg1
 
 '=============== Draw scales ================
 'C, D scales (main) -------------------------------------
 x = x0
 i = 0
 DO WHILE i<=900
   SELECT CASE x
     CASE IS <2
       h = 1
     CASE IS <4
       h = 2
     CASE ELSE
       h = 5
   END SELECT
   xx = firstXX+LOG(x)*SCALE
   d=7
   IF i MOD 5 = 0 THEN d=d+2
   IF i MOD 10 = 0 THEN d=d+3
   IF i MOD 100 = 0 THEN d=d+4
   LINE xx,CDline,xx,CDline-d,1,gra
   LINE xx,CDline+2,xx,CDline+2+d,1,gra
   IF i MOD 100 = 0 THEN
     TEXT xx-3,CDline-27,LEFT$(STR$(x),1),,7,1,gra,bg2
     TEXT xx-3,CDline+27,LEFT$(STR$(x),1),,7,1,gra,bg2
   ELSE
     IF i MOD 10 = 0 AND x<2 THEN
       TEXT xx-7,CDline-24,"1."+RIGHT$(STR$(x-1),1),,7,1,gra,bg2
       TEXT xx-7,CDline+24,"1."+RIGHT$(STR$(x-1),1),,7,1,gra,bg2
     END IF
   END IF
   i = i+h
   x = x+h*h0
 LOOP
 lastXX=xx
 
 'Pi mark on C,D scales -------------------------------------
 xx = firstXX+LOG(ACOS(-1))*SCALE
 d=5
 dd=12
 TEXT xx-3,CDline-28,"pi",,7,1,gra,bg2
 TEXT xx-3,CDline+28,"pi",,7,1,gra,bg2
 LINE xx,CDline-dd,xx,CDline-dd-d,1,gra
 LINE xx,CDline+2+dd,xx,CDline+2+dd+d,1,gra
 '
 'L scale -------------------------------------
 n=200
 h=(lastXX-firstXX)/n
 FOR i = 0 TO n
   x=i/200
   xx=firstXX+i*h
   d=7
   IF i MOD 2 = 0 THEN d=d+2
   IF i MOD 10 = 0 THEN d=d+6
   IF i MOD 20 = 0 THEN d=d+4
   LINE xx,Lline,xx,Lline-d,1,gra
   IF i MOD 20 = 0 THEN
     TEXT xx-8,Lline-24,STR$(x,1,1),,7,1,gra,bg1 '+4*(i=200)
     '#gr "\";right$(using("#.#",x), 3 + (i=200))
   END IF
 NEXT i
 '
 'A, B scales (square) -------------------------------------
 oldFirstXX=firstXX
 FOR k=1 TO 2
   x = x0
   i = 0
   DO WHILE i<=900
     SELECT CASE x
       CASE IS <2
         h = 2
       CASE IS <5
         h = 5
       CASE ELSE
         h = 10
     END SELECT
     xx = firstXX+LOG(x)/2*SCALE
     d=7
     IF i = 50 THEN d=d+3
     IF i MOD 10 = 0 THEN d=d+2
     IF i MOD 100 = 0 THEN d=d+5
     LINE xx,ABline,xx,ABline-d,1,gra
     LINE xx,ABline+2,xx,ABline+2+d,1,gra
     IF i MOD 100 = 0 THEN
       TEXT xx-3,ABline-27,LEFT$(STR$(x),1),,7,1,gra,bg2
       TEXT xx-3,ABline+27,LEFT$(STR$(x),1),,7,1,gra,bg2
     END IF
     i = i+h
     x = x+h*h0
   LOOP
   firstXX = xx
 NEXT k
 '
 'K scale (cube) -------------------------------------
 firstXX= oldFirstXX
 FOR k=1 TO 3
   x = x0
   i = 0
   DO WHILE i<=900
     SELECT CASE x
       CASE IS <3
         h = 5
       CASE IS <6
         h = 10
       CASE ELSE
         h = 20
     END SELECT
     xx = firstXX+LOG(x)/3*SCALE
     d=7
     IF i MOD 10 = 0 THEN d=d+2
     IF i MOD 50 =0 THEN d=d+3
     IF i MOD 100 = 0 THEN d=d+5
     LINE xx,Kline,xx,Kline-d,1,gra
     IF i MOD 100 = 0 THEN
       TEXT xx-3,Kline-27,LEFT$(STR$(x),1),,7,1,gra,bg1
     END IF
     i = i+h
     x = x+h*h0
   LOOP
   firstXX = xx
 NEXT
 '
 ' S scale (sine)
 ' todo
 '
 ' T scale (tangent)
 ' todo
 '
 'labels -------------------------------------
 TEXT 15,Kline-10,"K",,7,1,gra,bg1
 TEXT 15,ABline-12,"A",,7,1,gra,bg2
 TEXT 15,ABline+5,"B",,7,1,gra,bg2
 TEXT 15,Lline-10,"L",,7,1,gra,bg1
 TEXT 15,CDline-12,"C",,7,1,gra,bg2
 TEXT 15,CDline+5,"D",,7,1,gra,bg2
 TEXT 15,Sline-10,"S",,7,1,gra,bg1
 TEXT 15,Tline-10,"T",,7,1,gra,bg1
 
 BLIT READ 1,10,Tedge,MM.HRES,ABline-Tedge,2
 BLIT READ 2,10,CDline,MM.HRES,Ledge-CDline,2
 SPRITE READ 3,10,ABline+1,MM.HRES,CDline-ABline,2
 ' make cursor as sprite
 CLS
 BOX 10,Tedge-5,50,12,1,RGB(CYAN),RGB(CYAN)
 BOX 10,Ledge-2,50,12,1,RGB(CYAN),RGB(CYAN)
 LINE 35,Tedge-10,35,Ledge+10,1,gra
 
 SPRITE READ 4,10,Tedge-5,50,Ledge-Tedge+15,2
 
 PAGE WRITE 1
 BLIT WRITE 1,10,Tedge
 BLIT WRITE 2,10,CDline
 SPRITE SHOW 3, slidepos, ABline,0
 SPRITE SHOW 4,cursorpos,Tedge-5,0
 
 TEXT MM.HRES/2,Ledge+20,"Left and right to shift slide",CM
 TEXT MM.HRES/2,Ledge+35,"Up and Down to shift cursor",CM
 TEXT MM.HRES/2,Ledge+50,"Shift for rapid, ctrl for slow",CM
 TEXT MM.HRES/2,Ledge+65,"Or drag with a mouse",CM
 TEXT MM.HRES/2,Ledge+85,"Q to quit",CM
 TEXT MM.HRES - 40,5,"QUIT",LT,1,1,RGB(RED),RGB(WHITE)
 PAGE COPY 1 TO 0 ,b
 
 DO
   IF KEYDOWN(0) > 0 THEN
     kp = KEYDOWN(1)
     sp = KEYDOWN(7)' either shift key
     IF sp = 2 OR sp = 32 THEN nudge = 1 ELSE nudge = 0 ' single step or continuous
     IF sp = 8 OR sp = 128 THEN sp = 10 ELSE sp = 1 ' shift key for rapid movement
     SELECT CASE kp
       CASE 128
         cursorpos = MIN(cursorpos + sp,WW-3)
       CASE 129, 161
         cursorpos = MAX(cursorpos - sp,1-WW)
       CASE 131, 163
         slidepos = MIN(slidepos + sp,WW-3)
       CASE 130
         slidepos = MAX(slidepos - sp,1-WW)
       CASE 113
         quit = 1
     END SELECT
     IF nudge THEN
       DO : LOOP UNTIL KEYDOWN(0) = 0 ' single step with 'ctrl' key
     ENDIF
   ENDIF
   IF mouse_port >= 0 THEN ' we have a mouse
     mx = MOUSE(x,mouse_port)
     my = MOUSE(y,mouse_port)
     GUI CURSOR mx,my
     IF MOUSE(L,mouse_port) = 1 THEN
       IF oldlmb = 0 THEN ' left button just pressed.
         IF MOUSE(x,mouse_port)> MM.HRES-40 AND MOUSE(y,mouse_port)<18 THEN quit = 1
         oldmx = mx
         oldlmb = 1
       ENDIF
     ELSE
       oldlmb = 0
     ENDIF
     ' move the slide with the mouse
     IF oldlmb = 1 AND my > ABline AND my < CDline THEN
       slidepos = MIN(slidepos + mx-oldmx,WW-3)
       slidepos = MAX(slidepos,1-WW)
       oldmx=mx
     ENDIF
     ' move the cursor with the mouse
     IF oldlmb = 1 AND (ABS(my -Tedge)<25 OR ABS(my -Ledge)<25) THEN
       cursorpos = MIN(cursorpos + mx-oldmx,WW-3)
       cursorpos = MAX(cursorpos,1-WW)
       oldmx=mx
     ENDIF
   ENDIF
   PAUSE 10
   moveslide
 LOOP UNTIL quit = 1
 
 ' tidy up things
 CLS
 PAGE WRITE 0
 MODE 1,8
 CLS
 IF mouse_port >= 0 THEN
   CONTROLLER MOUSE CLOSE mouse_port
   GUI CURSOR OFF
 ENDIF
END
 
SUB moveslide
 IF slidepos <> oldpos OR cursorpos <> oldcursorpos THEN
   SPRITE HIDE 4
   IF slidepos <> oldpos THEN SPRITE SHOW 3, slidepos, ABline, 0
   SPRITE SHOW 4, cursorpos,Tedge-5,0
   oldpos = slidepos
   oldcursorpos = cursorpos
   PAGE COPY 1 TO 0 ,b
 ENDIF
END SUB
 


 

Last edited: 08 February, 2021