Electronics > Projects, Designs, and Technical Stuff

D8085AC ROM and 8279 finding keycodes

<< < (4/4)

Dom87:
Thanks All. :)
I shall take a look and see.

Dom87:
Thanks for the tips so far everyone.
I think I've made some significant process, but I'm still not quite there yet, and I refuse to be beaten!  |O :)

It has been quite an enjoyable project learning how the older processors used to work.

I was wondering if I could ask for some further advice on a particular section of code please? I'm not entirely sure what it is doing.
Any help or guidance would be great.

I found a particular sub-routine (L0DA5) that seems to validate/lookup the first character of a command string. For example; a command string might be "F12.4HZ". It seems to take the first character, e.g. 'F' and then checks a look-up table to ensure that it exists.

It is clearly a loop routine, counting down from 10 in decimal (A in hex). I believe it adds 3 to the D register on every loop to increase the HL pair.
I believe the HL pair refers to a particular address within the program, starting from 0DFE. Looking at this particular section of code, this seems to back up my understanding of what is going on.


My question is this: If/When it does the look-up, does it take any notice of the op-codes, such as "F     mov b,m" or is it simply ignored?
I'm trying to work out what value is used later on in the program.

L0DA5

--- Code: ---0DA5 L0DA5: ; ##### Validation/Lookup(?) Routine: This is only called from L0C59 when a command is in memory. ####
0DA5 : 0E 0A "  " mvi c,00AH ; L0DAD is loop and this initialises it as a countdown from 10.
0DA7 L0DA7:
0DA7 : 21 FE 0D "!  " lxi h,00DFEH ; Start of look-up table address?
0DAA : 11 03 00 "   " lxi d,00003H
0DAD L0DAD: ; ### Loop - This seems to be validating the first command character. ###
0DAD : BE " " cmp m ; 'F'/46, 'A'/41, 'O'/4F, 'W'/57, 'M'/4D, 'N'/4E, 'Y'/59, 'S'/52, etc.
0DAE : C8 " " rz ; Returns if zero. i.e. the character is a match.
0DAF : 19 " " dad d
0DB0 : 0D " " dcr c ; Decrements the countdown loop from 10 dec / A Hex.
0DB1 : C2 AD 0D "   " jnz L0DAD ; If it reaches zero, then we know we have an error. I think.
0DB4 : F6 80 "  " ori 080H ; Only reaches here if invalid command.
0DB6 : C9 " " ret

--- End code ---


0DFE

--- Code: ---0DFE : 46 "F" mov b,m
0DFF : 20 " " rim
0E00 : 01 41 21 " A!" lxi b,02141H
0E03 : 01 4F 22 " O"" lxi b,0224FH
0E06 : 01 57 23 " W#" lxi b,02357H
0E09 : 04 " " inr b
0E0A : 4D "M" mov c,l
0E0B : 27 "'" daa
0E0C : 03 " " inx b
0E0D : 4E "N" mov c,m
0E0E : 2C "," inr l
0E0F : 02 " " stax b
0E10 : 59 "Y" mov e,c
0E11 : 30 "0" sim
0E12 : 02 " " stax b
0E13 : 52 "R" mov d,d
0E14 : 2E 00 ". " mvi l,000H
0E16 : 53 "S" mov d,e
0E17 : 2D "-" dcr l
0E18 : 00 " " nop
0E19 : 5A "Z" mov e,d

--- End code ---

Thanks for your help.  :phew: :-+

duak:
It's been a long time since I worked with 8085 so I may have made a misteak or too.

Your analysis of the code makes sense.  Subroutine L0DA5 successfully exits with HL pointing to the command letter it matched. 

I edited the table at 0DFE to see if there was a pattern between the command letters.  Since there are two bytes, I thought they might be the addresses of subroutines somewhere to do some particular task.  That is, the code calling L0DA5 will increment HL by 1 and jump to or call the subroutine referenced by the two following bytes.  I don't think so here because the first characters of the pair are too close together to identify subroutine entry points.  And to answer your question, I don't think these bytes are opcodes.

0DFE : 46      "F"
       20 01
0E01:  41               'A'
       21 01
0E04 : 4F               'O'
       22 01
0E09 : 57               'W'
       23 04
0E0A : 4D      "M"
       27 03
0E0D : 4E      "N"
       2C 02
0E10 : 59      "Y"
       30 02
0E13 : 52      "R"
       2E 00
0E16 : 53      "S"
       2D 00
0E19 : 5A      "Z"

The second byte of the pair could be the number, size or type of parameters that could be expected following the command letter.  If so, the first byte of the pair could specify the variable that would receive the numbers following the command letter.  It may be coincidence, but for the first few entries the sum of the two bytes is the first byte of the next pair.  eg 20 + 01 = 21, 21 + 01 = 22, 22 + 01 = 23, 23 + 04 = 27  It breaks down after that but there might be some underlying relationship between the two bytes.

We'd need more code to decipher what it's doing.

Dom87:
Thanks Duak. That makes complete sense and now looking at it from a slightly different perspective I can see that it is using the next value in the address.
I've taken your idea of the table and restructured as to how I think it is looking up data.

As you suggest, I think it is using the two values that follow the matched character. In the table below, these are columns '1st Val' and '2nd Val'.
I think it loads the 1st value from the lookup table at 0C74 in L0C59, after it has performed the lookup for the first character by calling L0DA5 at 0C69.

Any ideas what it might be doing between 0C74 and 0C77?
I'm not sure I fully understand what the commands "xchg" and "db" are trying to do.



L0DA5 (Shown in my previous post) is called from L0C59, which seems to be the main branch that loads a character in sequence and then validates/manipulates it.


L0C59
Main command routine. I believe this loads each character in the command string in sequence and performs checks.
It appears to start with loading the first character. e.g. 'F' by calling L0DF4 and then validating it using the lookup table as described in the earlier post (same sub-routine).


--- Code: ---0C59 L0C59: ; ########## Main command routine ##########
0C59 : CD F4 0D "   " call L0DF4 ; Retrieves the next character in the command string. I believe this is the first character.
0C5C : 3A 26 B7 ":& " lda XB726
0C5F : B7 " " ora a
0C60 : C2 DA 0C "   " jnz L0CDA
0C63 : 7E "~" mov a,m ; I think a single character is moved into the A register.
0C64 : FE 3F " ?" cpi 03FH ; Checks against 63 decimal. ASCII this is a question mark. Is that what it is checking for?
0C66 : CA 36 0D " 6 " jz L0D36 ; Jump if character is 63 / Question mark. This will load the next character and try to validate it.
0C69 : CD A5 0D "   " call L0DA5 ; This seems to validate the first character command.
0C6C : C2 83 0D "   " jnz L0D83 ; Err Msg. Jump if first character not recognised? L0D83 places 91H into L register and 001 into the A register.
0C6F : 3E 01 "> " mvi a,001H
0C71 : 32 26 B7 "2& " sta XB726
0C74 : 23 "#" inx h ; INcrementeXtended register. This looks at the 1st value in the lookup table after match (0DFE)
0C75 : EB " " xchg ; Exchange contents of HL register pair with DE register pair. Is the lookup table value? e.g. W = 23?
;
0C76 : ED " " db 0EDH ; directs the assembler to reserve one byte of memory and initialize the byte with the specified value
;
0C77 : 7C "|" mov a,h
0C78 : B7 " " ora a
0C79 : FA C5 0C "   " jm L0CC5 ; Jump if minus
0C7C : CA C5 0C "   " jz L0CC5 ; Jump if zero. Basically this is jump if zero or less than.
0C7F : 3D "=" dcr a
0C80 : C2 8E 0C "   " jnz L0C8E ; Jumps if there is a command.
0C83 : E5 " " push h
0C84 : CD C6 0D "   " call L0DC6 ; This seems to be finding the end of the command string. I think. Needs double-checking.
0C87 : E1 " " pop h
0C88 : DA 83 0D "   " jc L0D83 ; Jump if carry. Error Msg. 9-1
0C8B : C3 7B 0D " { " jmp L0D7B
;
0C8E L0C8E:
0C8E : E5 " " push h
0C8F : CD F4 0D "   " call L0DF4 ; Retrieves the next character in the command string.
0C92 : CD B7 0D "   " call L0DB7 ; This subtracts from the accumulator 30H. I believe this converts a hexadecimal number to a number.
0C95 : E1 " " pop h
0C96 : DA 83 0D "   " jc L0D83 ; Error Msg. 9-1
0C99 : BC " " cmp h
0C9A : D2 83 0D "   " jnc L0D83 ; Jumps here if invalid command. It is known at at this point if it is an invalid command. Such as "N2"
0C9D : 25 "%" dcr h
0C9E : 25 "%" dcr h
0C9F : 67 "g" mov h,a
0CA0 : CA B5 0C "   " jz L0CB5 ; Jump if zero. It jumps with command in memory. "N0"
0CA3 : 7D "}" mov a,l
0CA4 : FE 23 " #" cpi 023H
0CA6 : 7C "|" mov a,h
0CA7 : C2 B1 0C "   " jnz L0CB1 ; Jump not zero.
0CAA : D6 01 "  " sui 001H ; SUbtract Immediate from Accumulator
0CAC : D2 B1 0C "   " jnc L0CB1 ; Jump no carry. It jumps here with "W2," in memory.
0CAF : 3E 03 "> " mvi a,003H

--- End code ---



L0DF4
I think this simply loads the next character in the string from memory.

--- Code: ---0DF4 L0DF4: ; ##### This seems to retrieve the next character in the command #####
0DF4 : 2A 28 B7 "*( " lhld XB728 ; Load HL pair using Direct addressing from memory location
0DF7 : 23 "#" inx h ; INcrementeXtended register. This instruction will be used to add 1 to the present content of the rp
0DF8 : 22 28 B7 ""( " shld XB728 ; Store HLpair using Direct addressing in memory location
0DFB : 2B "+" dcx h
0DFC : 7E "~" mov a,m ; Carriage Return (OxD) loaded into A register or Line Feed.
0DFD : C9 " " ret ; ~~~~~~~~~ End of sub-routine ~~~~~~~~~~~~~~~~~~

--- End code ---


L0DB7
I think this converts next character (i.e. number) to integer. e.g. 37 Hex is 7, subtracting 30 hex from it becomes 7.

--- Code: ---0DB7 L0DB7: ; ########### Converts a hexadecimal number to a number?? ############
0DB7 : D6 30 " 0" sui 030H ; Subtract from accumulator. The command character is in the accumulator.
0DB9 : D8 " " rc ; Return if carry. Not sure what scenario.
0DBA : FE 0A "  " cpi 00AH ; ComPare Immediate with Accumulator
0DBC : 3F "?" cmc ; Complement the carry flag.
0DBD : C9 " " ret ; Returns here if "W2,", "N2," in command string.

--- End code ---


Thanks!

Dom87:
Well, I've finally worked out the major bits of it. After much  |O and  :rant:

It turns out this is how it works.

1. A button is pressed on the panel. The 8279 then stores the value in FIFO encoded 2-key lockout.
Meaning the value is DB7 = Ctrl key, DB7 Shift key. DB5 is scan line 2, DB4 scan line 1, DB3 scan line 0 and DB2 to DB0 are the key value in an encoded format.
It means that in my case, the entire keyboard is in the range of C3 - F7 (converting binary to hexadecimal).

2. The main program loops round but continuously checks the FIFO ram. If there is something in memory it is read at address 0510. It then uses a lookup table at 075D.
So for example, F1 then becomes 2F at 07BE. 40 signifies that the feature is unavailable or not used.

3. I believe it then raises various software interrupts, but mainly RST 3 to perform another lookup based on the mapped value (e.g. 2F) to set the program counter and arrive at a specified address.


The table I uploaded before, as shown below is for validating and mapping GPIB commands (L0C59). The 1st Val column maps to the same values as the keyboard. So where the keyboard maps F1 to 2F. A command starting with the ASCII character 'Z' will map to the same value of 2F. From there it executes the same software interrupts and ends up at the same addresses.

The 2nd Value column in the table represents the type of value it can accept.

80 seems to be a three digit number.
00 is a two digit number.
Anything between 02 and 09 are single digit numbers.
01 is a value with a suffix. e.g. MV, V, KHZ, HZ.




What a learning curve!  :phew:

Navigation

[0] Message Index

[*] Previous page

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod