Emulating a mainframe

General FreeBASIC programming questions.
Gablea
Posts: 988
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Emulating a mainframe

Postby Gablea » Aug 12, 2018 15:29

Hi everyone

I was wondering if you all can help with a question.

I remember using a old dumb terminal that was connected to a Linux mainframe and allowed me to edit update delete items from a data table.

Does anyone know how they would have done the input screen?

Image

As you may see the “text” boxes are fields that are green and when you type the text is black (invented)

I know they would only Be text mode so how would they do that? (And would the same metholds work in a ascii only program in FreeBASIC)
bcohio2001
Posts: 489
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: Emulating a mainframe

Postby bcohio2001 » Aug 13, 2018 1:37

Yes, all text mode can be done like what is displayed.

The "grid boxes" are drawn using ascii codes 169 - 218. Using Code Page 437.

Text is printed by:

Code: Select all

Color Green, Black
Print "Current Date: ……"


And the input is:

Code: Select all

Color Black, Green
Input A
caseih
Posts: 1296
Joined: Feb 26, 2007 5:32

Re: Emulating a mainframe

Postby caseih » Aug 13, 2018 3:10

Unix programs would use codes, similar to ANSI codes, to instruct the terminal screen to move the cursor, set the color, and draw characters. So boxes were simply drawn on the screen much like you do it now in FB, with "locate"-like commands, printing box drawing characters. Each character set had certain box-drawing characters you could write, like the other reply mentions. Since terminals were remote, there was no way for the unix program to ask the terminal to read back to it the existing contents of the display. So when a box needed to be popped up asking for input, the program would simply draw them on the screen, overwriting the background characters. After the box was done, the program would then redraw the entire screen (sometimes this was quite noticeably slow), erasing the popup box. This is actually the technique I would use on FB. Printing to the text console is fast enough nowadays that it would hardly be noticeable, and your program could be smart about only reprinting the areas that need to be reprinted. And actually this is really how GUI windows work under the hood also--the program just redraws pieces of the screen when windows disappear or move.

Years ago, the common need for drawing "windows" on the terminal and requesting keyboard input, combined with the need to understand special codes for displaying and keyboard input, led to the development of common libraries to automate this. The modern version of these libraries is called ncurses. There's even a port of it to Windows, called pdcurses. ncurses handles things like keyboard input (ctrl, alt combinations, special keys, key codes for letters and function keys), output (move cursor, set color, print text, box drawing), primitive text-based windows, and even mouse events. FB does rely on a part of ncurses called libtinfo to handle differences in the various types of terminal emulators used on Linux, but FB does not actually use ncurses itself for printing. Instead FB implements many things similar to ncurses in the runtime library for commands like LOCATE, PRINT, COLOR, INPUT, etc.

So the short answer to your question is yes, the same methods used by older unix programs can be done in text mode with FB with only the built-in commands, such as locate, print, color, input, etc. Years ago I wrote a simple text input field routine that would use inkey$ to make a simple field editor using whatever colors (inverse background or just underlines to mark the field). Could use arrow keys, had insert, delete, etc. You'd want to implement something similar as the INPUT command is fairly limited in terms of editing (can't throw in an existing value). I'll have to dig up the code and post it here.
Gablea
Posts: 988
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Emulating a mainframe

Postby Gablea » Aug 13, 2018 7:43

Thanks for the advice guys I am thinking about doing a basic program that I could use on my linux server and tuning it from a dumb terminal this has all given me a idea as how to do that I would have to come up with some simple screen designs as I’m sure they would be limited to what can be displayed and no tab support (like we have in windows etc)

@caseih
If you do not mind I would appreciate seeing your code as I will admit keyboard support has never been my strong point.
caseih
Posts: 1296
Joined: Feb 26, 2007 5:32

Re: Emulating a mainframe

Postby caseih » Aug 13, 2018 14:00

Sure I can find it. It's made for qb/fblite, but could be adapted to run in normal FB. Give me a couple of days to put it together with a brief example of how to use it.
Gablea
Posts: 988
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Emulating a mainframe

Postby Gablea » Aug 13, 2018 15:47

@caseih
meany thanks. I do like my old systems :) I assume if I was to run this via a serial terminal on a Linux machine it would still work (I assume I can have 2 terminal connected to the machine at one time)
MrSwiss
Posts: 2763
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Emulating a mainframe

Postby MrSwiss » Aug 13, 2018 16:15

@Gablea,

if you are that much into 'old style', you may want to look at/read:
ASCII Art at Wikipedia ...
I've used that (simple frames) even in simple batch-jobs ...
batch-menues, to be more precise, however, in the late 1980th.

(And, I wouldn't want to go back there, there is simply no viable
reason, to do so!)
angros47
Posts: 1421
Joined: Jun 21, 2005 19:04

Re: Emulating a mainframe

Postby angros47 » Aug 13, 2018 17:06

That kind of interface, drawn using only ASCII character, is called TUI (Text User Interface). Google for it, there are several libraries designed to help for it.
caseih
Posts: 1296
Joined: Feb 26, 2007 5:32

Re: Emulating a mainframe

Postby caseih » Aug 13, 2018 18:00

I disagree about never going back. TUIs are alive and well and serve very useful purposes. I use several text mode programs with TUIs (menus, windows of sorts) on a regular basis. Remotely and locally. A GUI app will never replace these specific needs, though many have tried over the years.
Last edited by caseih on Aug 13, 2018 19:19, edited 1 time in total.
Gablea
Posts: 988
Joined: Apr 06, 2010 0:05
Location: Northampton, United Kingdom
Contact:

Re: Emulating a mainframe

Postby Gablea » Aug 13, 2018 18:47

I think a TUI is ideal for a keyboard based till application just need to work out how to do large fonts (like using xfont but would that work in text mode)
jj2007
Posts: 843
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Emulating a mainframe

Postby jj2007 » Aug 13, 2018 23:47

bcohio2001 wrote:The "grid boxes" are drawn using ascii codes 169 - 218. Using Code Page 437
Thanks for the inspiration: The console isn't completely dead yet ;-)
grindstone
Posts: 547
Joined: May 05, 2015 5:35
Location: Germany

Re: Emulating a mainframe

Postby grindstone » Aug 14, 2018 10:08

@Gablea: This is "my" substitution of the INPUT statement (I call it "stringmod.bi"). The options to imitate keystrokes with mouse and joystick and of running a plugin may be a little overhead for you, but you can submit an initial string to modify:

Code: Select all

Type tJoyBack
   up_ As String
   right_ As String
   down_ As String
   left_ As String
End Type
Dim Shared tJoyBackZero As tJoyBack

Declare Operator = (jr1 As tJoyBack, jr2 As tJoyBack) As Integer
Operator = (r1 As tJoyBack, r2 As tJoyBack) As Integer
   If r1.up_ <> r2.up_ Then Return 0
   If r1.right_ <> r2.right_ Then Return 0
   If r1.down_ <> r2.down_ Then Return 0
   If r1.left_ <> r2.left_ Then Return 0
   Return -1
End Operator

Operator <> (r1 As tJoyBack, r2 As tJoyBack) As Integer
   If r1.up_ <> r2.up_ Then Return -1
   If r1.right_ <> r2.right_ Then Return -1
   If r1.down_ <> r2.down_ Then Return -1
   If r1.left_ <> r2.left_ Then Return -1
   Return 0
End Operator

Type tMouseBack
   left_ As String
   middle_ As String
   right_ As String
   forward_ As String
   back_ As string
End Type
Dim Shared tMouseBackZero As tMouseBack   

Operator = (r1 As tMouseBack, r2 As tMouseBack) As Integer
   If r1.left_ <> r2.left_ Then Return 0
   If r1.middle_ <> r2.middle_ Then Return 0
   If r1.right_ <> r2.right_ Then Return 0
   If r1.forward_ <> r2.forward_ Then Return 0
   If r1.back_ <> r2.back_ Then Return 0
   Return -1
End Operator

Operator <> (r1 As tMouseBack, r2 As tMouseBack) As Integer
   If r1.left_ <> r2.left_ Then Return -1
   If r1.middle_ <> r2.middle_ Then Return -1
   If r1.right_ <> r2.right_ Then Return -1
   If r1.forward_ <> r2.forward_ Then Return -1
   If r1.back_ <> r2.back_ Then Return -1
   Return 0
End Operator

Declare Function stringmod(text As String = "", mode As Integer = 0, _
                           mouseback As tMouseBack = tMouseBackZero, _
                           joyback As tJoyBack = tJoyBackZero, _
                           callback As Any Ptr = 0) As String
Declare Function joysubst OverLoad () As Integer
Declare Function joysubst (top_ As String, right_ As String, _
                           left_ As String, bottom_ As String) As String
Declare Function joysubst (joyback As tJoyBack) As String
Declare Function mousesubst OverLoad (left_ As String = "", middle_ As String = "", _
                                     right_ As String = "", forward_ As String = "", _
                                     back_ As String = "" ) As String
Declare Function mousesubst(mouseback As tMouseBack) As String

Function stringmod(text As String = "", mode As Integer = 0, _
                           mouseback As tMouseBack = tMouseBackZero, _
                           joyback As tJoyBack = tJoyBackZero, _
                           callback As Any Ptr = 0) As String
'the submission of 'mode' is optional, default is 0
'mode0 --> normal function
'mode1 --> returns after 'arrow up', 'arrow down', 'screen up' and 'screen down'
'mode2 --> treats joystick movements like arrow keys (up, down, right, left)
'mode4 --> only sets the variable 'lasttext' and returns
'mode8 --> adds a Chr(27) at the beginning of the retrun string if 'esc' key is pressed

'if  'mouseback' is submitted as a 6-character string (each 2 characters for left/mid/right),
' mouseklicks are treated like keystrokes.

'if a pointer to a callback routine is submitted, the input loop is redirected to this
' routine, which can optional return a string that is treated like a keyboard input afterwards.
   
  Dim As Integer ze, sp, co, gi, lock_, ms, mz, wheel, buttons, length
  Dim As Single joyx, joyy
  Dim As String g, remember, txt
  Dim plugin As Sub (address As Any Ptr, length As Any Ptr)
   
  Static As String lasttext, g_back
  Static As Integer mousewheel
     
  If (mode And 4) Then
     lasttext = text + " "
     Return text
  EndIf
 
  If lasttext = "" Then
     lasttext = " "
  EndIf
 
  txt = text + " "
  remember = txt
  co = Pos 'cursor offset
  ze = CsrLin
  sp = Len(txt) 'pointer to the character under the cursor
  lock_ = 0
     
  Locate ze, co, 1
  Print txt;
  Locate ze, sp+co-1, 1
 
 
  Do
    'input
    plugin = callback 'set pointer to the plugin
    If (callback <> 0) And (g_back = "") Then 'call plugin
       g_back = String(200,Chr(0)) 'allocate memory for the return string
       length = Len(g_back) 'max length of the return string
       plugin(StrPtr(g_back),@length) 'call plugin
      g_back = Left(g_back,length) 'write return string to buffer
    EndIf
   
    If (mouseback <> tMouseBackZero) Then
        g_back += mousesubst(mouseback)
    EndIf
           
     If (joyback <> tJoyBackZero) Then 'treats joystick like keys
       g_back += joysubst(joyback)
     EndIf
           
    If g_back = "" Then
       g = InKey
    Else 'process return string
       If Left(g_back,1) = Chr(255) Then 'control character
          g = Left(g_back,2) 'imitated keystroke
          g_back = Mid(g_back,3) 'shorten return string
       Else 'normal character
          g = Left(g_back,1) 'imitated keystroke
          g_back = Mid(g_back,2) 'shorten return string
       EndIf
    EndIf
       
    If Len(g) = 1 Then 'normal character
       If g[0] > 31 Then 'character
        txt = Left(txt, sp - 1) + g + Mid(txt, sp)
        sp += 1
        Locate ze, co, 0
        Print txt;
        Locate ze, sp+co-1, 1
       Else 'control character
        Select Case g[0]
           Case 8 ' back key
            If sp > 1 Then
              txt = Left(txt, sp - 2) + Mid(txt, sp)
              sp -= 1
              Locate ze, co, 0
              Print txt;
              Locate ze, sp+co-1, 1
            End If
           Case 27 'esc
            If (mode And 8) Then
               txt = Chr$(27) + txt
            Else
               txt = remember 'old string
            EndIf
            g = Chr$(13) 'terminate
        End Select
      End If
    ElseIf Len(g) = 2 Then 'control character
       gi = g[1]
      Select Case gi 'control character
         Case 75 'left arrow -> cursor left
          If sp > 1 Then
            sp -= 1
            Locate ze, sp+co-1, 1
          End If
         Case 77 'right arrow -> cursor right
          If sp < Len(txt) Then
            sp += 1
            Locate ze, sp+co-1, 1
          ElseIf txt = " " Then 'set old string
             txt = lasttext
             sp = Len(txt)
             Print txt;
             Locate ze, sp+co-1, 1
          End If
         Case 14 'back -> delete character left of cursor
          If sp > 1 Then
            txt = Left(txt, sp - 1) + Mid$(txt, sp)
            sp -= 1
            Locate ze, co, 0
            Print txt;
            Locate ze, sp+co-1, 1
          End If
         Case 83 'del -> delete character right of cursor
          If sp < Len(txt) Then
            txt = Left(txt, sp - 1) + Mid$(txt, sp + 1)
            Locate ze, co, 0
            Print txt;
            Locate ze, sp+co-1, 1
          End If
         Case 71 'pos1 -> set cursor to the beginning of the string
          sp = 1
          Locate ze, sp+co-1, 1
         Case 79 'end -> set cursor to the end of the string
          sp = Len(txt)
          Locate ze, sp+co-1, 1
         Case Else
            If (mode And 1) Then
            txt = g + Chr$(ze) + Chr$(co) + txt 'return control character and cursor position
            g = Chr$(13)
          EndIf
      End Select
    Else 'no key
       Sleep 1
    End If
  Loop Until g = Chr$(13) 'return
      
  lasttext = txt
  Return Left(txt, Len(txt) - 1)
  Locate ze, sp+co-1, 0 'cursor off
             
End Function

Function joysubst () As Integer
   
   Dim As Single joyx, joyy
   Dim As Integer buttons, output_
   Static As Integer lock_ = 0
   Static As Double locktime
   
   output_ = 0 'default value no key pressed
      
   If GetJoystick (0, buttons, joyx, joyy) Then
      'no joystick connected
   Else
      If joyx < -.5 Then 'left
        output_ = 4
      ElseIf joyx > .5 Then 'right
         output_ = 2
      EndIf
      If joyy < -.5 Then 'top
         output_ = 1
      ElseIf joyy > .5 Then 'bottom
         output_ = 3
      EndIf
   EndIf
   
   If output_ = 0 Then 'no key pressed, set delay to 0
      lock_ = 0
   EndIf

   Select Case lock_ 'delay mode
      Case 0 'immediate execution
         If output_ Then 'key pressed
            lock_ = 1 'delay mode
           locktime = Timer + 0.3 'delay for 1st keystroke
         EndIf
      Case 1 'key is held down
         If Timer > locktime Then 'check if delay time is over
            lock_ = 2 'repeat mode
            locktime = Timer + 0.07 'delay value for repetition mode
         Else 'delay time not over
            output_ = 0
         EndIf
      Case 2 'delay mode
         If Timer > locktime Then 'check if delay time is over
            locktime = Timer + 0.07 'set time for the next delay loop
         Else 'delay time not over
            output_ = 0
         EndIf
   End Select
   
   Return output_
 
End Function

Function joysubst (up_ As String, right_ As String, _
                   down_ As String, left_ As String) As String
         
   Select Case joysubst()
      Case 0 'no key
         Return ""
      Case 1 'up
         Return up_
      Case 2 'right
         Return right_
      Case 3 'down
         Return down_
      Case 4 'left
         Return left_
   End Select
   
End Function

Function joysubst (joyback As tJoyBack) As String
         
   Select Case joysubst()
      Case 0 'no key
         Return ""
      Case 1 'top
         Return joyback.up_
      Case 2 'right
         Return joyback.right_
      Case 3 'bottom
         Return joyback.down_
      Case 4 'left
         Return joyback.left_
   End Select
   
End Function

Function mousesubst(mouseback As tMouseBack) As String
   Return mousesubst(mouseback.left_, mouseback.middle_, mouseback.right_, _
                    mouseback.forward_, mouseback.back_)
End Function

Function mousesubst (left_ As String = "", middle_ As String = "", _
                    right_ As String = "", forward_ As String = "", _
                    back_ As String = "") As String
   Dim As Integer ms, mz, wheel, buttons
   Static As Integer mousewheel
   
   GetMouse (ms,mz,wheel,buttons)
   If (buttons And 1) Then 'left mouse button
      Function = left_
   ElseIf (buttons And 4) Then 'mid mouse button
      Function = middle_
   ElseIf (buttons And 2) Then 'right mouse button
      Function = right_
   EndIf
             
   If wheel < mousewheel Then
      Function = back_ 'mouse wheel back
      mousewheel = wheel
   ElseIf wheel > mousewheel Then
      Function = forward_ 'mouse wheel forward
      mousewheel = wheel
   EndIf
   
   Do 'wait for mouse button release
      GetMouse (ms,mz,wheel,buttons)
      Sleep 1
   Loop While buttons

End Function
marcov
Posts: 2623
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Emulating a mainframe

Postby marcov » Aug 14, 2018 10:40

search for "vt220 escape sequences" Note that the linux console still uses such escape sequences.
jj2007
Posts: 843
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Emulating a mainframe

Postby jj2007 » Aug 14, 2018 11:44

grindstone wrote:...you can submit an initial string to modify
Your code compiles but doesn't do anything. Can you show a usage example?
grindstone
Posts: 547
Joined: May 05, 2015 5:35
Location: Germany

Re: Emulating a mainframe

Postby grindstone » Aug 14, 2018 13:44

Eagerly. Start the snippet, modify the preset sentence like in a textbox, then press return.

Code: Select all

#Include "stringmod.bi"

Dim As String textout
Dim As tMouseBack mouseBack

'simple stringmod example
Print "Preset string: ";
textout = stringmod("This is a stringmod example")
Locate 5,1
Print "Modified string: ";textout
Print
Print

'simple example how to substitute the mouse buttons and -wheel
Print "Now press your mouse buttons and move the wheel. End with RETURN"
With mouseBack 'preset mouse buttons and wheel with text
   .left_    = "You pressed the left mouse button ** "
   .middle_  = "You pressed the middle mouse button ** "
   .right_   = "You pressed the right mouse button ** "
   .forward_ = "You moved the wheel forward ** "
   .back_    = "You moved the wheel backward ** "
End With

Print
textout = stringmod("",, mouseBack)
     
Print
Print
Print textout

Sleep

Return to “General”

Who is online

Users browsing this forum: No registered users and 4 guests