Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Memory address problem

  1. Apr 5, 2013 #1
    I am trying to setup digital control of slow simple peripherals using the UART.
    I am trying to locate the UART in RAM and it is not working. I have a '486 running windows 3.1.1 and using Microsoft quick basic.
    This code prints numbers which are supposed to change when the com2 uart sees a change to its handshake lines. It does not respond when I apply a minus 3V to the four handshaking lines.

    REM Psnoop.bas looks at serial port addresses
    'WARNING AVOID location 238 = hex EE it causes a shutdown and restart. I have no idea why.
    'com1 03f8, com2 02f8, com3 3e8, com4 2e8
    'Pick COM2 since COM1 is broken..
    'Ports directory: 8 data, 9 irc, a irdat, b lc, c handshake t, d handshake t, e handshake r, f scratch
    DEF SEG = 0
    'com2 &H2F8= 760, KBD= &H60= 96, Clock &H70 = 112 None of these work.
    PRINT "Reading RAM."
    a = 760 'Base address Com2
    PRINT a
    FOR j = 1 TO 40 'Keep looking 40 times for a change while I plug in wires to pins.
    FOR i = 0 TO 7 ' Reads all 8 registers in the UART
    x% = INP(a + i) 'PEEK does not work here. Input does
    PRINT x%;
    NEXT i
    SLEEP 2 'Give me a chance to look at the screen.
    NEXT j
  2. jcsd
  3. Apr 5, 2013 #2


    User Avatar
    Homework Helper

    You probably need to program the UART to enable certain pins on it. Link to a document about the UART:

  4. Apr 9, 2013 #3
    Post has been overcome by events:

    My post I hope shows my concern that I would never get this to work because I would never find the correct address. However some testing got results.

    I looked at the "C" command Peek, and it has the same segment:eek:ffset form as the d command in Debug so I figured it would get the same bad result.

    So I added part of the above program to some quick basic communication code and produced something that got results.
    This doesn't do anything useful but at least the input function works on the UART:

    'Filename com4way.bas, 10/8/12
    OPEN "Com2:2400,n,8,1,RS,DS0" FOR RANDOM AS #1 LEN = 1
    PRINT "Ready"
    PRINT #1, CHR$(10), CHR$(13) 'Line feed carrage return to start fresh.
    PRINT #1, "Quick BASIC, com 2, q to end."
    a = 760
    PRINT #1, CHR$(10), CHR$(13) '10=line feed, 13=carrage return
    DO WHILE k$ <> "q" 'changing INKEY$ to k$ made the transmit work.
    20 k$ = INKEY$
    IF k$ <> "" THEN PRINT #1, k$;
    IF ASC(k$ + CHR$(0)) = 13 THEN PRINT #1, CHR$(10);
    IF LOC(1) > 0 THEN PRINT (INPUT$(1, 1));
    FOR i = 0 TO 7
    x% = INP(a + i) 'PEEK does not work here.
    PRINT x%;
    NEXT i
    SLEEP 1
    25 CLOSE #1

    So now I know I do not have an unknown memory location problem.
    I put a loopback connector in the Com port which shorted pins 2-3 transmit and receive, and also had request to send connected to clear to send (this is crucial on my machine).

    Running the above code I see changes at the address 760 which is the receive input byte. It echos the keyboard code.

    Also I see changes around 766 which I hope is some handshake line.
    I don't know what made the UART come alive. It might be the Open command. I have plenty more tests to do.
    I guess the only thing to ask now is if there is any interest?
  5. Apr 9, 2013 #4


    User Avatar
    Homework Helper

    Peek is used to access memory, while inp() reads an I/O port. You need to use port I/O functions (the other should be outp() for ouput) to access the UART.

    I assume that the Open command made it work by doing the initial programming to setup the UART to send and receive at some specified baud rate.
  6. Apr 17, 2013 #5
    Some control over the handshake lines

    Thanks for the help. I have made some progress.
    The following program, written in the quickbasic, supplied with Windows 3.1.1, exercises the com port handshake, by "counting up" the "transmit" lines RTS and DTR, and displaying a hex number to indicate the "receive" lines CD, RI, DSR, CTS, level. It transmits serial data unreliably through my loop back connector.
    I used COM2 because COM1 does not work.

    'Filename comyway.bas, Finished 4/14/13
    'Counts up and outputs RTS and DTR signals 9pins7and4 as 8 9 A B in middle.
    'Receives CD RI DSR CTS first part of last number. Watch your levels.
    'Not considered reliable for serial data. 13 (error) shows too often.
    'Low =0 High =1 on screen and in my test box 1= led on.
    SCREEN 13
    PRINT "Start"
    j = 0
    a = 760
    OPEN "Com2:2400,n,8,1,RS,DS0" FOR RANDOM AS #1 LEN = 1
    PRINT #1, "A" ' CHR$(10), CHR$(13) 10=line feed, 13=carrage return
    DO WHILE k$ <> "q" 'changing INKEY$ to k$ made the transmit work.
    20 k$ = INKEY$
    IF k$ <> "" THEN PRINT #1, k$
    ' IF ASC(k$ + CHR$(0)) = 13 THEN PRINT #1, CHR$(10);
    IF LOC(1) > 0 THEN PRINT (INPUT$(1, 1));
    ' PRINT
    SLEEP 1
    j = j + 1
    k = j MOD 4
    OUT &H2FC, (k + 8) 'The 8 keeps it from crashing.
    IF j = 200 THEN GOTO 50
    50 PRINT "end"
    25 CLOSE #1
    PRINT "closed"
    SCREEN 0

    FOR i = 0 TO 7
    x% = INP(a + i) 'PEEK does not work here.
    CASE 0
    PRINT x%;
    CASE 1
    PRINT " ";
    CASE 2
    PRINT " ";
    CASE 3
    PRINT " ";
    CASE 4
    a$ = HEX$(x%)
    PRINT a$; " ";
    CASE 5
    PRINT " ";
    CASE 6
    a$ = HEX$(x%)
    PRINT a$; " ";
    CASE 7
    NEXT i

    I do not know why OPEN must be commanded to access the handshake lines.
    I do not know what the bus interface to the UARTS looks like.
    I do not know the difference between peek and input.
    I do not know what has to be done to the UART on its input pins to make it run.
  7. Apr 18, 2013 #6
    Usually in BASIC and in general, an Open is granting you private access and control. This is like you want to edit a document. You open it. That means nobody else should be able to come along while you are half way done, make changes to it, and then the result is corrupted. And that nobody includes your operating system changing pins or state to something it thinks it wants. When you Open it you should be able to depend on having control of that and all the data going in and out of it until you later Close it or until your program ends and the operating system then does a Close for you.

    If you Google
    16650 datasheet
    then you should find a number of different places showing you what the bus interface to the UART looks like. It will be a handful of bytes, some letting you read handshake input pins, some letting you set write handshake output pins, one reading input data bytes one writing output data bytes, etc. If you haven't read a document like that in the past it might take a little getting used to.

    Usually in BASIC peek(n) is a function that reads the byte at memory address n and hands it to your program. Usually in BASIC Input() is a function that either reads from the keyboard or sometimes from something redirected to look to the program like it came from the keyboard. Peek looks at memory, Input expects you to type a line of text and hit <enter>.

    Sometimes the electronics that controls the state machine of the UART demands that the handshake lines be at certain levels, either high or low. That is typicaly called "hardware handshake." Decades ago it was "wire pin 4 to 5 and wire pin 6 to 8 to 20." If you look up the old 25 pin RS232 connector you can see those jumpers are connecting RequestToSend to ClearToSend and connecting DataSetReady to DataCarrierDetect to DataTerminalReady. If the decades haven't corrupted those brain cells then these jumpers were enough to make any hardware handshake serial device willing to communicate. With the new 9 pin RS232 that looks like it should be 7 to 8 and 1 to 6 to 4. But you should verify those carefully to make certain I haven't made a mistake. And if you are trying to toggle one of those pins yourself for a single bit of input then that is a new set of conditions you need to know are correct.
  8. May 26, 2013 #7
    Switch to Parallel Port

    Thanks Bill and the rest. I have gone as far as I can with the serial port and now am turning to the parallel port. I wrote the test programs below in Microsoft QBasic on a '486 running windows 3.1.1. The last does not work. I have no idea how to fix it. The data direction bit does not seem to work. Also below my spacing is gone.

    1 -----------------------------------------
    REM Filename LPTcount.bas was LPT3o Works OK 5/12/13
    '--------------WARNING Print Manager Conflict----------------------
    REM Tests the printer port data lines D0-D7 and C0-C3 by counting up.
    'The first two C lines are inverted and maybe the last.
    REM Also shows ascii of typed key.
    INPUT "Is Print Manager shut down? ", A$
    IF A$ <> "y" THEN END
    lpt1% = 888 '&h378
    lpt2% = 632 '&h278
    lpt3% = 956 '&h3BC
    lpt% = lpt1% 'Choose port address
    OUT lpt%, 0 'Output to D lines 2-9
    OUT lpt% + 2, 0 'Output to C lines 1, 14, 16, 17
    SLEEP 2
    FOR i% = 1 TO 255 'Count up in binary.
    OUT lpt%, i% 'Output to D lines 2-9
    OUT lpt% + 2, i% 'Output to C lines 1, 14, 16, 17
    PRINT i%;
    FOR j = 1 TO 100 'Delay, SLEEP takes too long.
    x = i% + j
    NEXT j
    'SLEEP 1
    NEXT i%
    PRINT "Type a number in 0-7. q to end"; TIME$ 'The time is not needed.
    WHILE A$ <> "q"
    100 A$ = INKEY$
    IF A$ = "" THEN 100
    c% = ASC(A$)
    d% = c% - 48 'Convert ascii number to real number.
    IF A$ = "q" THEN 200
    IF d% < 0 OR d% > 7 THEN 100
    d% = 2 ^ d% 'Gets one LED.
    200 OUT lpt%, d% 'Send to D
    OUT lpt% + 2, d% 'Send to C
    PRINT A$; c%, 'Print the pressed key.
    OUT lpt%, 0 'Else it ends with a 65h. =01000001

    REM Filename: LPTin2.bas looks at parallel port Status inputs.
    '--------------WARNING Print Manager Conflict----------------------
    REM Test the printer port input at Address+1. It reads the switches.
    PRINT "Bits 3 and 4 to lines 10 and 11 are not straightforward." 'Something strange happens.
    INPUT "Is Print Manager shut down? ", a$
    IF a$ <> "y" THEN END
    'lpt1% = 888 = &H378: lpt2% = 632 = &H278: lpt3% = 956 = &H3BC
    lpt% = 888 + 1
    OUT lpt% - 1, 0
    REM the input part.
    a$ = "O"
    FOR i = 1 TO 200
    a$ = INKEY$
    IF a$ = "q" THEN END
    s% = INP(lpt%)
    a = 0: b = 0: c = 0: d = 0: e = 0: f = 0: g = 0: h = 0
    IF (s% OR 128) = s% THEN a = 1
    IF (s% OR 64) = s% THEN b = 1
    IF (s% OR 32) = s% THEN c = 1
    IF (s% OR 16) = s% THEN d = 1
    IF (s% OR 8) = s% THEN e = 1
    IF (s% OR 4) = s% THEN f = 1
    IF (s% OR 2) = s% THEN g = 1
    IF (s% OR 1) = s% THEN h = 1
    PRINT s%, a; b; c; d; e; f; g; h
    SLEEP 1
    NEXT i

    3 ------------------------------------------------------
    'LPTDinNG.bas was LPTin3 try to read the Data register. Fails.
    INPUT "Is Print Manager shut down? ", A$
    IF A$ <> "y" THEN END
    'The Data register fails to change to input.
    Address = 888: REM 889 = port address, other addresses could be 633 or 956
    PRINT "A (0) is ground, (1) is high or unterminated. "
    DIM D(8)
    i = 0
    OUT Address + 2, 47 '00101111 Change the data direction for Data register.
    WHILE A$ <> "q" 'Manual quit.
    100 A$ = INKEY$
    i = i + 16 'Try all bits.
    i = i MOD 256
    OUT Address + 2, i 'Has no effect.
    'OUT Address + 2, 15 + 32 * i
    V = INP(Address)
    PRINT V, i,
    FOR j = 0 TO 7
    D(j) = 0
    NEXT j
    FOR j = 7 TO 0 STEP -1
    IF V > ((2 ^ j) - 1) THEN D(j) = 1: V = V - 2 ^ j
    PRINT D(j);
    NEXT j
    'dp = 0
    'FOR j = 0 TO 7
    'dp = dp + D(j)
    'NEXT j
    'PRINT dp
    SLEEP 1

    This is what I know about the Parallel Port.
    'The parallel port registers are as follows:

    'relative location 0 Data
    'bits 0-7 are pins 2-9

    'relative location 1 Status
    'bit 0 timeout if used output reads high
    'bit 1 not used reads high
    'bit 2 not used reads high
    'bit 3 input error Pin 15
    'bit 4 input select Pin 13
    'bit 5 input paper out Pin 12
    'bit 6 input ack Pin 10 bit 6,7 anded then shorted.
    'bit 7 input busy inverted Pin 11 bit 6,7 anded then shorted.
    'If pin 10 and 11 are both high then bit 6 and 7 are both 1.
    'Else 6 and 7 are 0.

    'relative location 2 Control
    'bit 0 output Strobe for D Pin 1 inverted
    'bit 1 output line feed Pin 14 inverted
    'bit 2 output init Pin 16 *
    'bit 3 output select Pin 17 inverted *
    'bit 4 interrupt enable for ack
    'bit 5 D line data direction 0 = output 1 = input Does not work.
    'bit 6 not used
    'bit 7 not used except where it is used instead of bit 5

    'Pins 18-25 are all ground. * Supposedly may be set to input
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook