outputting a character on the console from within hlasm (370) - mainframe

For fun I'm implementing brainfuck compilers translating bf to e.g. x86 assembly. Currently I'm working on bf to mainframe assembly. Dialect is "HLASM" and mainframe is one of IBM with a 370.
Sofar most of it works only emitting a character to the console of the operator fails: I only get spaces and it looks like an implicit linefeed is added (which I don't want).
Can anyone find my mistake?
* get a character to display
LLGC R6,0(R7)
* get a pointer to the buffer which will contain the char to displa
LA R5,BUFFER
* store character in buffer
STC R6,0(R5)
* get a pointer to the memory area describing the data to display
LA R1,MSGAREA
* invoke display char
SVC 35
MSGAREA EQU *
DC AL2(5)
DC XL2'00'
BUFFER DC C'!'

I would suggest writing to the SYSOUT DD to give you the flexibility to run either in batch (allocating SYSOUT in your JCL) or interactively (allocating SYSOUT to the terminal session which I believe is the default in TSO).
[entry logic, initialization and so forth]
OPEN (SYSOUT,OUTPUT)
PUT SYSOUT,RECORD
CLOSE SYSOUT
[exit logic]
RECORD DC CL80' '
SYSOUT DCB DDNAME=SYSOUT, X
DSORG=PS, X
MACRF=PM, X
RECFM=FB, X
LRECL=80
You might want to also look at the TPUT, TGET, and TPG macros for terminal I/O if you're okay with tying your program to running in TSO exclusively. Terminal I/O is kind of odd in a 3270 environment if you're used to streaming I/O as in Unix.
DCB is documented here. OPEN is documented here. PUT is documented here. CLOSE is documented here.

Related

Returning values from linux binary

First, let me say that I am very new to writing drivers so I apologize if my terminology is completely off.
I am attempting to write a driver to control an LED and read back some registers on my FPGA development board.
As nicely pointed out here I understand that I can supply my binary (or C program) input values by using (in my C program):
int main(int argc, char *argv[]) { /* ... */ }
So, as an example, in my Linux shell if I run:
root#socfpga:~# ./LED_BLINK 182
I can send an input integer of 182 to my binary that is being executed in the linux shell script. In my case this blinks my LED 182 times (this part works). So I know how to give my program inputs, but how do I properly extract outputs from my program?
My main questions are as follows:
1) In general, suppose my binary has variable(s) that I would like to return as outputs, how can I do this? Example, if I want my program to output the value at register 5, I input in the shell:
root#socfpga:~# ./LED_BLINK 1 5
The LED will blink once and then my shell will return the value at register 5 (this register is just a variable in the binary program).
Another way to describe what I am after, suppose if I have a single register (let's say it is a 16 bit value) and I would like my program to output that value, how can I properly achieve this? Can I pass a variable to my binary (such as a pointer?) and have my program write to that value? Can you provide an example of this or a link to a tutorial?
2) Similar to above, what if I have a list of registers (say 20 or more 16 bit values), how could my binary properly output these values ( a pointer array, maybe)?
3) I am sure that this process has a technical name. What is this 'technically' called (so that I can have smarter google search entries)?
Thank you for your help,
James
The most direct way to pass data between programs in a Unix setting is to use standard input and output "pipes" (also known as stdin and stdout).
By default the C statement "printf" will default to writing to stdout and you will see the output on the terminal by default or you can pass it to another program as input using the "|", or to another file-type operation using the ">" operand.
This is explained in more detail on this post: What does it mean to write to stdout in C?

Unexpected periodic, non-continuous output for OCaml program

Someone reports that given a stream of strings on the serial port which is pipelined to the OCaml program below, the output of the program is not continuous, but instead it appears in chunks (of a few tens of lines), as if buffered.
What can be the cause of the non-continuous output?
(The output buffer should be flushed after each new line due to the use of '%!'. So this shouldn't be the cause, right?)
let tp = ref 0
let get_next_entry ic =
try
let (ts, pred, v) = Scanf.fscanf ic " #%d %s#(%d)\n" (fun x y z -> (x,y,z)) in
Printf.printf "at timepoint %d (timestamp %d): %s(%d)\n%!" !tp ts pred v;
incr tp;
true
with End_of_file ->
false
let _ =
while get_next_entry stdin do
()
done
The OCaml version used is 4.05.
It is a threefold problem. From the least likely to the most likely.
The glitching output
It is all in the eye of the beholder, as how the program output will look like depends on the environment in which it is run, i.e., on a program that runs your program and renders this on a visual device. In other words, it involves a lot of variables that are beyond the context of this program.
With that said, let me explain what flush means for the printf function. The printf facility relies on buffered channels. And each channel is roughly a pair of a buffer and system-specific file descriptor. When someone (including printf) outputs to a channel, the information first goes into the buffer and remains there until the next portion of information overrides the buffer (i.e., there is no more space in the buffer) or until the flush function is called explicitly. Then the buffer is flushed, which means that the information in the buffer is transferred to the operating system (e.g., using the write system call or library function).
What happens afterward is system dependent. If the file descriptor was associated with a regular file, then you might expect that the information will be passed to it entirely(though the file system has its own hierarchy of caches, so there're caveats also). If the descriptor was associated with a Unix-style shell process through a pipe, then it will go into the pipe's buffer, extracted from it by the shell and printed using a terminal interface, usually fulfilled with some terminal emulator. By default shells are line-buffered, so the line should be printed as a whole unless the user of the shell changes its parameters somehow.
Basically, I hope you get the idea, it is not your program which is actually manipulating with the terminal and lighting up pixels on your monitors. Your program is just outputting data and some other program is receiving this data and drawing it on the screen. And this some other program (a terminal, or terminal emulator, e.g., minicom) is making this output glitchy, not your program. Your program is doing its best to be printed correctly - full line or nothing.
Your program is glitching
And it is. The in_channel is also buffered, so it will accumulate a few bytes before calling sprintf. Therefore, you can just read from the buffered channel and expect a realtime response to it. The most reliable way for you would be to use the Unix module and process the input using your own buffering.
The glitching input
Finally, the input program can also give you the information in chunks. This is especially true for serial interfaces, so make sure that you have correctly set up your terminal interface using the Unix.tcsetattr function. In particular, when your program is blocked on the input, the operating system may decide not to wake it up on each arrived character or line. This behavior is controlled by the terminal interface (see the Canonical and Non-canonical modes. If your input doesn't have newlines, then you shall use the non-canonical mode).
Finally, the device itself could be acting jittering, and if you have an oscilloscope nearby you can observe the signals it is sending. And make sure that you have configured your serial port as prescribed in the user manual of your device.
One possibility is that fscanf is waiting until it sees everything it's looking for.

Why does the sys_read system call end when it detects a new line?

I'm a beginner in assembly (using nasm). I'm learning assembly through a college course.
I'm trying to understand the behavior of the sys_read linux system call when it's invoked. Specifically, sys_read stops when it reads a new line or line feed. According to what I've been taught, this is true. This online tutorial article also affirms the fact/claim.
When sys_read detects a linefeed, control returns to the program and the users input is located at the memory address you passed in ECX.
I checked the linux programmer's manual for the sys_read call (via "man 2 read"). It does not mention the behavior when it's supposed to, right?
read() attempts to read up to count bytes from file descriptor fd
into the buffer starting at buf.
On files that support seeking, the read operation commences at the
file offset, and the file offset is incremented by the number of bytes
read. If the file offset is at or past the end of file, no bytes are
read, and read() returns zero.
If count is zero, read() may detect the errors described below. In
the absence of any errors, or if read() does not check for errors, a
read() with a count of 0 returns zero and has no other effects.
If count is greater than SSIZE_MAX, the result is unspecified.
So my question really is, why does the behavior happen? Is it a specification in the linux kernel that this should happen or is it a consequence of something else?
It's because you're reading from a POSIX tty in canonical mode (where backspace works before you press return to "submit" the line; that's all handled by the kernel's tty driver). Look up POSIX tty semantics / stty / ioctl. If you ran ./a.out < input.txt, you wouldn't see this behaviour.
Note that read() on a TTY will return without a newline if you hit control-d (the EOF tty control-sequence).
Assuming that read() reads whole lines is ok for a toy program, but don't start assuming that in anything that needs to be robust, even if you've checked that you're reading from a TTY. I forget what happens if the user pastes multiple lines of text into a terminal emulator. Quite probably they all end up in a single read() buffer.
See also my answer on a question about small read()s leaving unread data on the terminal: if you type more characters on one line than the read() buffer size, you'll need at least one more read system call to clear out the input.
As you noted, the read(2) libc function is just a thin wrapper around sys_read. The answer to this question really has nothing to do with assembly language, and is the same for systems programming in C (or any other language).
Further reading:
stty(1) man page: where you can change which control character does what.
The TTY demystified: some history, and some diagrams showing how xterm, the kernel, and the process reading from the tty all interact. And stuff about session management, and signals.
https://en.wikipedia.org/wiki/POSIX_terminal_interface#Canonical_mode_processing and related parts of that article.
This is not an attribute of the read() system call, but rather a property of termios, the terminal driver. In the default configuration, termios buffers incoming characters (i.e. what you type) until you press Enter, after which the entire line is sent to the program reading from the terminal. This is for convenience so you can edit the line before sending it off.
As Peter Cordes already said, this behaviour is not present when reading from other kinds of files (like regular files) and can be turned off by configuring termios.
What the tutorial says is garbage, please disregard it.

how is terminfo delay/padding implemented in TTYs?

I have been looking at terminfo and it has delays, e.g. $<5>, in the capability strings. I was trying to see through running tput under strace how is the delay implemented, i.e., whether it is implemented by, say, nanosleep or by inserting NUL or other characters. This is the command I have tried to run and trace:
TERM=ansi77 strace -o log.txt tput dl1
I chose dl1 on ansi77 because it is defined as dl1=\E[M$<5*/>. However, all I see in the trace is write of 3 bytes:
write(1, "\33[M", 3) = 3
So, my question is, how the delay actually implemented? Padding characters or simple process/thread sleep?
Can I observe it in terminal emulator or do I need real hardware terminal to see it?
Is there any flaw in trying to reproduce it with tput?
Agreeing with #cliffordheath that padding is done by adding padding characters, reference to the available documentation can help.
Hardware terminals did not cease to exist, they are still supported by ncurses. Without padding, these old terminals would not work properly (dropping or mangling your output). The vt100 entry uses padding, that for xterm does not.
The terminfo name for the padding character is pad; pc is a termcap name (see terminfo(5)):
pad_char pad pc padding char
(instead of null)
The terminfo manual page has a lengthy paragraph (in Types of Capabilities) dealing with padding. There are two types of padding supported in terminfo format (advisory and mandatory), distinguished by their format. termcap supports only the latter (using different syntax of course), and unlike terminfo all of the delays happen at one time (making escape sequences for "flash" generally not work).
The command-line tput program does more than act as a wrapper for the function tputs, but it uses that when outputting strings. The command-line program provides for outputting boolean, numeric and of course string capabilities.
The library call tputs has a parameter for the number of affected lines which is taken into account (like baud rate) in computing delays.
In OP's question
dl1=\E[M$<5*/>
specifies a delay proportional to the number of lines affected (marked by the "*" character). The number of lines affected for the command-line tput utility is 1. It calls putp to do this. However, that in turn calls delay_output, and that calls baudrate. The last function is initialized only when the terminal is initialized. The command-line tput does not initialize the terminal, so delays will not work for that. You should see (given the right speed) delays using the library itself.
ncurses also provides time delays with napms (milliseconds), which is different from padding.
Where delays are implemented, it's done by transmitting pad characters, traditionally NUL characters. The pad character can be changed by a termdata/terminfo setting of the variable pad or pc.
Pad characters are necessary because the program cannot know when the previously-sent characters have actually been written for it to start a CPU delay. Even if the kernel is done with them after an output flush the characters might still be buffered in the output device UART.
The number of required pad characters is calculated from the baud rate - so it depends on that information being available and accurate.
The tputs routine in the library implements padding (see man 3 tputs). I suspect that the command-line tool does too, since it's basically just a wrapper.

instruction set emulator guide

I am interested in writing emulators like for gameboy and other handheld consoles, but I read the first step is to emulate the instruction set. I found a link here that said for beginners to emulate the Commodore 64 8-bit microprocessor, the thing is I don't know a thing about emulating instruction sets. I know mips instruction set, so I think I can manage understanding other instruction sets, but the problem is what is it meant by emulating them?
NOTE: If someone can provide me with a step-by-step guide to instruction set emulation for beginners, I would really appreciate it.
NOTE #2: I am planning to write in C.
NOTE #3: This is my first attempt at learning the whole emulation thing.
Thanks
EDIT: I found this site that is a detailed step-by-step guide to writing an emulator which seems promising. I'll start reading it, and hope it helps other people who are looking into writing emulators too.
Emulator 101
An instruction set emulator is a software program that reads binary data from a software device and carries out the instructions that data contains as if it were a physical microprocessor accessing physical data.
The Commodore 64 used a 6502 Microprocessor. I wrote an emulator for this processor once. The first thing you need to do is read the datasheets on the processor and learn about its behavior. What sort of opcodes does it have, what about memory addressing, method of IO. What are its registers? How does it start executing? These are all questions you need to be able to answer before you can write an emulator.
Here is a general overview of how it would look like in C (Not 100% accurate):
uint8_t RAM[65536]; //Declare a memory buffer for emulated RAM (64k)
uint16_t A; //Declare Accumulator
uint16_t X; //Declare X register
uint16_t Y; //Declare Y register
uint16_t PC = 0; //Declare Program counter, start executing at address 0
uint16_t FLAGS = 0 //Start with all flags cleared;
//Return 1 if the carry flag is set 0 otherwise, in this example, the 3rd bit is
//the carry flag (not true for actual 6502)
#define CARRY_FLAG(flags) ((0x4 & flags) >> 2)
#define ADC 0x69
#define LDA 0xA9
while (executing) {
switch(RAM[PC]) { //Grab the opcode at the program counter
case ADC: //Add with carry
A = X + RAM[PC+1] + CARRY_FLAG(FLAGS);
UpdateFlags(A);
PC += ADC_SIZE;
break;
case LDA: //Load accumulator
A = RAM[PC+1];
UpdateFlags(X);
PC += MOV_SIZE;
break;
default:
//Invalid opcode!
}
}
According to this reference ADC actually has 8 opcodes in the 6502 processor, which means you will have 8 different ADC in your switch statement, each one for different opcodes and memory addressing schemes. You will have to deal with endianess and byte order, and of course pointers. I would get a solid understanding of pointer and type casting in C if you dont already have one. To manipulate the flags register you have to have a solid understanding of bitwise operations in C. If you are clever you can make use of C macros and even function pointers to save yourself some work, as the CARRY_FLAG example above.
Every time you execute an instruction, you must advance the program counter by the size of that instruction, which is different for each opcode. Some opcodes dont take any arguments and so their size is just 1 byte, while others take 16-bit integers as in my MOV example above. All this should be pretty well documented.
Branch instructions (JMP, JE, JNE etc) are simple: If some flag is set in the flags register then load the PC to the address specified. This is how "decisions" are made in a microprocessor and emulating them is simply a matter of changing the PC, just as the real microprocessor would do.
The hardest part about writing an instruction set emulator is debugging. How do you know if everything is working like it should? There are plenty of resources for helping you. People have written test codes that will help you debug every instruction. You can execute them one instruction at a time and compare the reference output. If something is different, you know you have a bug somewhere and can fix it.
This should be enough to get you started. The important thing is that you have A) A good solid understanding of the instruction set you want to emulate and B) a solid understanding of low level data manipulation in C, including type casting, pointers, bitwise operations, byte order, etc.

Resources