RPGLE Compile Error: "The Name Or Indicator Is Not Defined" - rpgle

I am taking an introductory course to IBM iSeries and Rational Developer, and I'm having difficulty compiling one of my RPGLE programs for a lab... Unfortunately, the lab is just a walkthrough of code we are supposed to compile without much explanation, so I have absolutely no clue about what I'm doing....
When I compile my program MARKSRPG.RPGLE, most of my errors say "The Name Or Indicator Is Not Defined"... I don't know what this means, and I'm unable to move ahead to see if what I have coded works thus far.
(UPDATE: I've made corrections to the suggestions, and now I'm getting different errors. "The types of the left and right hand side do not match in the EVAL operation", and "Operands are not compatible with the type of operator.)
The program is broken up into two files: MARKSRPG.RPGLE and MARKSDSP.DSPF. Here is the code for both, but my errors only show up on MARKSRPG.RPGLE
MARKSDSP:
A R RECORD1
A 1 33'Marks Calculator'
A 2 2USER
A 1 2SYSNAME
A 1 72DATE
A 4 24'Test 1:'
A 5 24'Test 2:'
A 6 24'Test 3:'
A 7 24'Labs:'
A 8 24'Exam:'
A TEST1 3 0B 4 32RANGE(0 100)
A TEST2 3 0B 5 32RANGE(0 100)
A TEST3 3 0B 6 32RANGE(0 100)
A LABS 3 0B 7 32RANGE(0 30)
A EXAM 3 0B 8 32RANGE(0 100)
A FIELD T B 2 71
A R RECORD2 CA03(03 'Exit')
A OVERLAY
A 10 23'Tests:'
A 11 18'Final Mark:'
A 12 17'Final Grade:'
A TESTOVRLL 3 0O 10 30
A NUMGRADE 3 0O 11 30
A GRADE 2X O 12 30
A 13 17'F3 - Exit'
MARKSRPG:
FMARKSDSP CF E WORKSTN
DLETGRADE S 1A
DTESTOVRLL S 3A
/FREE
EXFMT RECORD1;
DOW NOT(*IN03);
EXSR GETGRADE;
WRITE RECORD1;
EXFMT RECORD2;
IF *IN03= *OFF;
EXSR CLEARMARKS;
EXFMT RECORD1;
ENDIF;
ENDDO;
*INLR = *ON;
RETURN;
BEGSR GETGRADE;
LETGRADE = 'F';
TESTOVRLL = (TEST1 + TEST2 + TEST3)/3;
NUMGRADE = (TESTOVRLL/100*.30) + LABS +(EXAM/100*.35);
ENDSR;
BEGSR CLEARMARKS;
TEST1 = 0;
TEST2 = 0;
TEST3 = 0;
LABS = 0;
EXAM = 0;
TESTOVRLL = 0;
ENDSR;
/END-FREE
If you know of any useful resources for learning RPGLE and CLLE I'd appreciated it, and
any additional insight and help would be great too!
Thanks.

In your RPGLE member you have the wrong name for your display file. You have MARKSRPG instead of MARKSDSP.
I don't see LETGRADE defined anywhere either, that should go in your D specs.
D LETGRADE s 1a
I also don't see the subroutine CLEARMARKS defined anywhere. Since I also don't see an /end-free anywhere I'm going to assume you didn't paste all of the code for your RPGLE member.
Make those two changes I mentioned and then come back with any questions.
Here's a link to IBM's information center for the IBM i: http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/rzasd/sc09250802.htm

Related

Is Entrance into a Windows Critical Section an atomic operation?

I wrote an FFI for critical sections, and I wrote a test for it in Haxe.
Tests run in order defined (public functions are tests)
This test test_critical_section will intermittently hang and fail:
1 var criticalSection:CriticalSection;
2
3 #if master
4 public function test_init_critical_section() {
5 return assert(attempt({
6 criticalSection = synch.SynchLib.critical_section_init(SPIN_COUNT);
7 trace('criticalSection: $criticalSection');
8 }));
9 }
10 var criticalValue = 0;
11 var done = 0;
12 var numThreads = 50;
13 function work_in_critical_section(ID:Int, a:AssertionBuffer) {
14 sys.thread.Thread.create(() -> {
15 inline function threadMsg(msg:String)
16 trace('Thread ID $ID: $msg');
17
18
19 threadMsg("Attempting to enter critical section");
20 criticalSection.critical_section_enter();
21 threadMsg("Entering crtiical section. Doing work.");
22 Sys.sleep(Std.random(100)/500); // simulate work in section
23 criticalValue+= 10;
24 done++;
25 a.assert(criticalValue == done * 10);
26 threadMsg("Leaving critical section. Work done. done: " + done);
27 criticalSection.critical_section_leave();
28 if (done == numThreads) {
29 a.assert(criticalValue == numThreads * 10);
30 a.done();
31
32 }
33 });
34 }
35 #:timeout(30000)
36 public function test_critical_section() {
37 var a = new AssertionBuffer();
38 for (i in 0...numThreads)
39 work_in_critical_section(i, a);
40 return a;
41 }
But when I add Sys.sleep(ID/5); just before entrance into the critical section (on the blank line 18), the test passses every single time (with any number of threads). Without it, the test fails randomly (more often with a higher number of threads).
My conclusion from this test is that entrance to a critical section is not atomic, and multiple threads simultaneously attempting to enter may leave the critical section in an undefined state (leading to undefined/hanging behavior).
Is this the right conclusion or am I simply mis-using critical sections (and thus, the test needs to be re-written)? And if it is the right conclusion.. does this not mean that entrance into the critical section needs its own atomic locking/synchronization mechanism..? (and further, if that is the case.. what is the point of critical sections, why would I not just use whatever that atomic synchronization mechanism is?)
To me, this seems problematic, for example, consider 10 threads meet at a synchronization barrier (with a capacity of 10), and then all 10 need to proceed through a critical section immediately after the 10th thread arrives, does that mean I'd have to synchronize/serialize access to the critical section entrance method (for instance, by sleeping such as to ensure only one thread attempts to enter the section at a given tick, as done to fix the failing test above)?
The FFI is writen ontop of synchapi.h (see EnterCriticalSection)
You read done outside the critical section. That is a race condition. If you want to look at the value of done, you need to do it before you leave the critical section.
You might see a write to done from another thread, triggering the assert before the write to criticalValue is visible to the thread that saw the write to done.
If the critical section protects criticalValue and done, then it is an error to access either of them without being in the critical section unless you are sure every thread that might access them has terminated. Your code violates this rule.

Microphone has too large component of lower frequency

I use knowles sph0645lm4h-b microphone to acquire data, which is a 24-bits PCM format with 18 data presicion. Then the 24-bits PCM data is truncated to 18-bits data, because the last 6 bits is alway 0 according to the specification. After that, the 18-bits data is stored as a 32-bits unsigned integer. When the MSB bit is 0, which means it's a positive integer, and the MSB is 0, which means it's a negative integer.
After that, i find all data is positive, no matter which sound i used to test. I tested it with a dual frequency, and do a FFT, then I found the result is almost right except the lower frequency about 0-100Hz is larger. But i reconstructed the sound with the data, which i used for FFT algorithm. The reconstructed sound is almost right but with noise.
I use a buffer to store the microphone data, which is transmitted using DMA. The buffer is
uint16_t fft_buffer[FFT_LENGTH*4]
The DMA configuration is doing as following:
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI2->DR);
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)fft_buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_BufferSize = FFT_LENGTH*4;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
extract data from buffer, truncate to 18 bits and extends it to 32 bits and the store at fft_integer:
int32_t fft_integer[FFT_LENGTH];
fft_buffer stores the original data from one channel and redundant data from other channel. Original data is store at two element of array, like fft_buffer[4] and fft_buffer[5], which are both 16 bits. And fft_integer store just data from one channel and each data take a 32bits.This is why the size of fft_buffer Array is [FFT_LENGTH*4]. 2 elements are used for data from one channel and 2 element is used for the other channel. But for fft_integer, the size of fft_integer array is FFT_LENGTH. Because data from one channel is stored and 18bits can be stored in one element of type int32_t.
for (t=0;t<FFT_LENGTH*4;t=t+4){
uint8_t first_8_bits, second_8_bits, last_2_bits;
uint32_t store_int;
/* get the first 8 bits, middle 8 bits and last 2 bits, combine it to a new value */
first_8_bits = fft_buffer[t]>>8;
second_8_bits = fft_buffer[t]&0xFF;
last_2_bits = (fft_buffer[t+1]>>8)>>6;
store_int = ((first_8_bits <<10)+(second_8_bits <<2)+last_2_bits);
/* convert it to signed integer number according to the MSB of value
* if MSB is 1, then set all the bits before MSB to 1
*/
const uint8_t negative = ((store_int & (1 << 17)) != 0);
int32_t nativeInt;
if (negative)
nativeInt = store_int | ~((1 << 18) - 1);
else
nativeInt = store_int;
fft_integer[cnt] = nativeInt;
cnt++;
}
The microphone is using I2S Interface and it's a single mono microphone, which means that there is just half of the data is effective at half of the transmission time. It works for about 128ms, and then will stop working.
This picture shows the data, which i convert to a integer.
My question is why there is are large components of lower frequency although it can reconstruct the similar sound. I'm sure there is no problem in Hardware configuration.
I have done a experiment to see which original data is stored in buffer. I have done the following test:
uint8_t a, b, c, d
for (t=0;t<FFT_LENGTH*4;t=t+4){
a = (fft_buffer[t]&0xFF00)>>8;
b = fft_buffer[t]&0x00FF;
c = (fft_buffer[t+1]&0xFF00)>>8;
/* set the tri-state to 0 */
d = fft_buffer[t+1]&0x0000;
printf("%.2x",a);
printf("%.2x",b);
printf("%.2x",c);
printf("%.2x\n",d);
}
The PCM data is shown like following:
0ec40000
0ec48000
0ec50000
0ec60000
0ec60000
0ec5c000
...
0cf28000
0cf20000
0cf10000
0cf04000
0cef8000
0cef0000
0cedc000
0ced4000
0cee4000
0ced8000
0cec4000
0cebc000
0ceb4000
....
0b554000
0b548000
0b538000
0b53c000
0b524000
0b50c000
0b50c000
...
Raw data in Memory:
c4 0e ff 00
c5 0e ff 40
...
52 0b ff c0
50 0b ff c0
I use it as little endian.
The large low-frequency component starting from DC in the original data is due to the large DC offset caused by incorrectly translating the 24 bit two's complement samples to int32_t. DC offset is inaudible unless it caused clipping or arithmetic overflow to occur. There are not really any low frequencies up to 100Hz, that is merely an artefact of the FFT's response to the strong DC (0Hz) element. That is why you cannot hear any low frequencies.
Below I have stated a number of assumptions as clearly as possible so that the answer may perhaps be adapted to match the actualité.
Given:
Raw data in Memory:
c4 0e ff 00
c5 0e ff 40
...
52 0b ff c0
50 0b ff c0
I use it as little endian.
and
2 elements are used for data from one channel and 2 element is used for the other channel
and given the subsequent comment:
fft_buffer[0] stores the higher 16 bits, fft_buffer[1] stores the lower 16 bits
Then the data is in fact cross-endian such that for example, for:
c4 0e ff 00
then
fft_buffer[n] = 0x0ec4 ;
fft_buffer[n+1] = 0x00ff ;
and the reconstructed sample should be:
0x00ff0ec4
then the translation is a matter of reinterpreting fft_buffer as a 32 bit array, swapping the 16 bit word order, then a shift to move the sign-bit to the int32_t sign-bit position and (optionally) a re-scale, e.g.:
c4 0e ff 00 => 0x00ff0ec4
0x00ff0ec4<< 8 = 0xff0ec400
0xff0ec400/ 16384 = 0xffff0ec4(-61756)
thus:
// Reinterpret DMA buffer as 32bit samples
int32_t* fft_buffer32 = (int32_t*)fft_buffer ;
// For each even numbered DMA buffer sample...
for( t = 0; t < FFT_LENGTH * 2; t += 2 )
{
// ... swap 16 bit word order
int32_t sample = fft_buffer32 [t] << 16 |
fft_buffer32 [t] >> 16 ;
// ... from 24 to 32 bit 2's complement and rescale to
// maintain original magnitude. Copy to single channel
// fft_integer array.
fft_integer[t / 2] = (sample << 8) / 16384 ;
}

GBZ80 - ADC instructions fail test

I've been running Blarggs CPU tests through my Gameboy emulator, and the op r,r test shows that my ADC instruction is not working properly, but that ADD is. My understanding is that the only difference between the two is adding the existing carry flag to the second operand before addition. As such, my ADC code is the following:
void Emu::add8To8Carry(BYTE &a, BYTE b) //4 cycles - 1 byte
{
if((Flags >> FLAG_CARRY) & 1)
b++;
FLAGCLEAR_N;
halfCarryAdd8_8(a, b); //generates H flag based on addition
carryAdd8_8(a, b); //generates C flag appropriately
a+=b;
if(a == 0)
FLAGSET_Z;
else
FLAGCLEAR_Z;
}
I entered the following into a test ROM:
06 FE 3E 01 88
Which leaves A with the value 0 (Flags = B0) when the carry flag is set, and FF (Flags = 00) when it is not. This is how it should work, as far as my understanding goes. However, it still fails the test.
From my research, I believe that flags are affected in an identical manner to ADD. Literally the only change in my code from the working ADD instruction is the addition of the flag check/potential increment in the first two lines, which my test code seems to prove works.
Am I missing something? Perhaps there's a peculiarity with flag states between ADD/ADC? As a side note, SUB instructions also pass, but SBC fails in the same way.
Thanks
The problem is that b is an 8 bit value. If b is 0xff and carry is set then adding 1 to b will set it to 0 and won't generate carry if added with a >= 1. You get similar problems with the half carry flag if the lower nybble is 0xf.
This might be fixed if you call halfCarryAdd8_8(a, b + 1); and carryAdd8_8(a, b + 1); when carry is set. However, I suspect that those routines also take byte operands so you may have to make changes to them internally. Perhaps by adding the carry as a separate argument so that you can do tmp = a + b + carry; without overflow of b. But I can only speculate without the source to those functions.
On a somewhat related note, there's a fairly simple way to check for carry over all the bits:
int sum = a + b;
int no_carry_sum = a ^ b;
int carry_into = sum ^ no_carry_sum;
int half_carry = carry_into & 0x10;
int carry = carry_info & 0x100;
How does that work? Consider that bitwise "xor" gives the expected result of each bit if there is no carry going in to that bit: 0 ^ 0 == 0, 1 ^ 0 == 0 ^ 1 == 1 and 1 ^ 1 == 0. By xoring sum with no_carry_sum we get the bits where the sum differs from the bit-by-bit addition. sum is only different whenever there is a carry into a particular bit position. Thus both the half carry and carry bits can be obtained with almost no overhead.

Is there a way to access DHR on the Apple 2 from Applesoft Basic

When using Applesoft Basic on the Apple 2 with an 80 column card, is there a way to create DHR graphics using only POKE?
I have found a number of solutions using third party extensions such as Beagle Graphics, but I really want to implement it myself. I've searched my Nibble magazine collection, and basic books, but have been unable to find any detailed information.
Wikipedia:
Double High-Resolution The composition
of the Double Hi-Res screen is very
complicated. In addition to the 64:1
interleaving, the pixels in the
individual rows are stored in an
unusual way: each pixel was half its
usual width and each byte of pixels
alternated between the first and
second bank of 64KB memory. Where
three consecutive on pixels were
white, six were now required in double
high-resolution. Effectively, all
pixel patterns used to make color in
Lo-Res graphics blocks could be
reproduced in Double Hi-Res graphics.
The ProDOS implementation of its RAM
disk made access to the Double Hi-Res
screen easier by making the first 8 KB
file saved to /RAM store its data at
0x012000 to 0x013fff by design. Also,
a second page was possible, and a
second file (or a larger first file)
would store its data at 0x014000 to
0x015fff. However, access via the
ProDOS file system was slow and not
well suited to page-flipping animation
in Double Hi-Res, beyond the memory
requirements.
Wikipedia says that DHR uses 64:1 interlacing, but gives no reference to the implementation. Additionally Wikipedia says you can use the /RAM disk to access, but again gives no reference to the implementation.
I am working an small program that plots a simple version of Connet's Circle Pattern. Speed isn't really as important as resolution.
A member of the comp.sys.apple2.programmer answered my question at: http://groups.google.com/group/comp.sys.apple2.programmer/browse_thread/thread/b0e8ec8911b8723b/78cd953bca521d8f
Basically you map in the Auxiliary memory from the 80 column card. Then plot on the HR screen and poke to the DHR memory location for the pixel you are trying to light/darken.
The best full example routine is:
5 HGR : POKE 49237,0 : CALL 62450 : REM clear hires then hires.aux
6 POKE 49246,0 : PG = 49236
7 SVN = 7 : HCOLOR= SVN : P5 = .5
9 GOTO 100
10 X2 = X * 4 : CL = CO : TMP = 8 : FOR I = 3 TO 0 STEP -1 : BIT = CL >= TMP:
CL = CL - BIT * TMP : TMP = TMP * P5
20 X1 = X + I: HCOLOR= SVN * BIT
30 XX = INT (X1 / SVN): H = XX * P5: POKE PG + (H= INT (H)),0
40 XX = INT (( INT (H) + (( X1 / SVN) - XX)) * SVN + P5)
50 HPLOT XX,Y: POKE PG, 0: NEXT : RETURN
100 FOR CO = 0 TO 15 : C8 = CO * 8
110 FOR X = C8 TO C8 + SVN: FOR Y = 0 TO 10 : GOSUB 10 : NEXT : NEXT
120 NEXT
130 REM color is 0 to 15
140 REM X coordinate is from 0 to 139
150 REM Y coordinate is from 0 to 191

How to get status from POS Printer

I'm trying to find a way to get paper status from a POS printer; I think I would use GS a, GS r sequence but I cannot understand how to return info from the printer; I'm under Linux, where does the POS printer returns info about status?
I've finally solved my problem ... i use PHP on linux box, here is the code, hope to help anyone:
<?php
$device="/dev/usb/lp0";
$printer=fopen($device, 'w');
//La sequenza di ESCAPE DLE EOT n consente
//la trasmissione in realtime
//dello status
//n=1: printer status
//n=2: printer offline status
//n=3: error status
//n=4: paper roll sensor status
//Per n=4 i bits valorizzati sono:
//BIT Off/On Dec Desc
//0 Off 0 not used, fixed to Off
//1 On 2 not used, fixed to On
//2,3 Off 0 Paper adequate
//2,3 On 12 Paper near end detected
//4 On 16 Not used, fixed to On
//5,6 Off 0 Paper present
//5,6 Off 96 Paper roll end
//7 Off 0 Not used, fixed to Off
fwrite($printer,kbyte(16).kbyte(4).kbyte(4));
//fwrite($printer,kbyte(29).kbyte(73).kbyte(69));
fclose($printer);
$r_printer=fopen($device, 'r');
$ret=fgets($r_printer);
fclose($r_printer);
$bit_val=ord($ret[0]);
print "Retval=".$bit_val;
if(($bit_val & 12) || ($bit_val & 96))
print "******Out of paper******\n";
else
print "---Paper ok\n";
function kbyte($num) {
return pack('C', $num);
}
?>

Resources