Jump to content


New Members
  • Content Count

  • Joined

  • Last visited

Community Reputation

14 Good

About adel314

  • Rank
    Space Invader

Profile Information

  • Gender
  • Location
    Adelaide South Australia

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Just re-reading your comment on never having used XOP instructions, I thought I would pass my latest use of them on, which might be of interest to the community. Why I never thought of this before is surprising, and would have saved me months of debugging time over the years, but there you go. For example, if you define an XOP as say DEBUG using code similar to DXOP DEBUG,15 Then, in your programme code that needs to be debugged you can add the following: . . 014E 0200 0003 LI R0,3 0152 0201 0006 LI R1,6 0156 8040 C R0,R1 0158 2FE0 0208 DEBUG @TRACE_BUF 015C 8001 C R1,R0 015E 2FE0 0228 DEBUG @TRACE_BUF 0162 0A10 SLA R0,1 0164 2FE0 0248 DEBUG @TRACE_BUF . . 0200 TRACE_BUF: BSS 36 ;Used to store the trace data . and the code in DEBUG(XOP) can produce, during execution, something such as this: PC = 015C ST = 1004 R0 =0003 R1 =0006 R2 =0088 R3 =0000 R4 =0500 R5 =7285 R6 =8D77 R7 =574D R8 =F2C0 R9 =01C6 R10=0204 R11=9044 R12=8000 R13=D411 R14=1C7B R15=0004 PC = 0162 ST = D004 R0 =0003 R1 =0006 R2 =0088 R3 =0000 R4 =0500 R5 =7285 R6 =8D77 R7 =574D R8 =F2C0 R9 =01C6 R10=0204 R11=9044 R12=8000 R13=D411 R14=1C7B R15=0004 PC = 0168 ST = C004 R0 =0006 R1 =0006 R2 =0088 R3 =0000 R4 =0500 R5 =7285 R6 =8D77 R7 =574D R8 =F2C0 R9 =01C6 R10=0204 R11=9044 R12=8000 R13=D411 R14=1C7B R15=0004 The DEBUG XOP 15 code is simply (the formatting code is left out but if anyone is interested I can post it), ; ; NOW SAVE THE TRACE DATA ; XOP15: EE30 CECE MOV R14,*R11+ ;STORE PROGRAMME COUNTER FIRST EE32 CECF MOV R15,*R11+ ;STORE STATUS REGISTER EE34 0208 0010 LI R8,16 ;16 REGISTERS EE38 CEFD XOP_LOOP: MOV *R13+,*R11+ ;COPY REGISTERS EE3A 0608 DEC R8 EE3C 16FD JNE XOP_LOOP EE3E 022D FFE0 AI R13,-32 ;RESTOR WORKSPACE REGISTER LOCATION
  2. The problem with BLWP/RTWP is that after the first level of subroutine you have to begin saving the workspace pointers, status registers and return addresses etc so the overhead management soon becomes very complicated for nested systems. Using the XOPs you can avoid that are mimic and normal micro that microcodes the CALL, PUSH and POP functions. I have copied the CALL functions just for info. Of course in most circumstances you don't need to check for stackoverflow and this would reduce the code somewhat. As you suggest, if I don't want the overhead of a PUSH and POP, and provided the routine is local you can use MOV R3,@-2(SP) to push onto the stack and MOV @-2(SP),R3 to recover it. You can perform some fairly powerful pseudo instructions using XOPs which would yes be very similar to MACROs ; ;************************************************ ; CALL SUBROUTINE ; CALLING METHOD: CALL SUBROUTINE_ADDRESS ;************************************************* ; XOP6 MOV @2*R10(R13),R10 ;GET STACK POINTER DECT R10 C R10,@2*R9(R13) ;CHECK FOR STACK OVERFLOW JLE STACKERR ;O/P STACK OVERFLOW MESSAGE MOV R14,*R10 ;PUSH SAVED PC ONTO STACK MOV R11,R14 ;MOVE EA INTO R14 FOR CALL MOV R10,@2*R10(R13) ;UPDATE STACK POINTER RTWP ;NOTE WE ARE NOW USING THE ORIGINAL WP
  3. Yes, the exponent is handled separately, so in effect I am working on a 5 byte mantissa in R5, R6 and MSB of R7. This causes extra handling but I though I would be consistent with the original and keeping the representation within 3 registers just makes it neater.
  4. Yes, it is about integer arithmetic. The mantissa is a 40 bit integer. The problem that I see is that the TMS9900 performs two's complement arithmetic and the flags are based on that implementation.
  5. The integer maths are required to calculate the 40bit mantissa component oof the floating point routines. Here is a link to the original Z80 code. http://www.z80.info/zip/math.zip . For your info here here is the code for PUSH and POP , they are just standard XOP routines. ; ;************************************************* ; PUSH DATA/REGISTER ONTO THE STACK ; USES CALLER'S WP AND STACK POINTERS ;************************************************* ; XOP8 MOV @FREEMEM,@2*R9(R13) ;UPDATE FREE MEMORY POINTER IE STACK LIMIT MOV @2*R10(R13),R10 DECT R10 C R10,@2*R9(R13) ;CHECK FOR OVERFLOW JLE STACKERR MOV *R11,*R10 MOV R10,@2*R10(R13) RTWP ; ; POP DATA/REGISTER OFF STACK ; XOP9 MOV @2*R10(R13),R10 MOV *R10+,*R11 MOV R10,@2*R10(R13) RTWP
  6. Regarding the use of two's complement, I decided to use another method as the method I have posted earlier, is not 100% accurate, but from a coding perspective I think this updated method is accurate is reasonably compact and would appreciate your thoughts. The logic behind this is that a "Carry" or "Borrow" as we now it will always occur if the operand being subtracted (source) is logically larger than the destination operand, so using a Compare to test this allows us to use JH or JLE to detect the borrow. ; ; ;Subtract 40 bit Destination (R5,R6,R7)from another 40 bit Source (R1,R2,R3). ; ; 40 bit source: R1,R2,R3 with R1 being MS and R3 LS ; 40 bit destination: R5,R6,R7 with R5 being MS and R7 LS ; ; ; SUBAC: PUSH R1 PUSH R2 CLR R0 CB R3,R7 ;Check for borrow JLE SAC1 INC R2 ;Propogate the borrow JNC SAC1 INC R1 JNC SAC1 SETO R0 ; ; Now perform the subtract the R3 from R7 (LS) ; SAC1: SB R3,R7 ;no need to check for carry/overflow C R2,R6 JLE SAC2 INC R1 JNC SAC2 SETO R0 ; ; Now perform the subtract of R2 from R6 ; SAC2: S R2,R6 C R1,R5 JLE SAC3 SETO R0 ; ; Now the subtract the MSB registers R1 from R5 ; SAC3: S R1,R5 POP R2 POP R1 INC R0 ;Set the carry flag if carry in the MSB occured RET
  7. In certain places the Z80 code with the use of the carry flag makes some of the arithmetic much simpler than the TMS9900 but in most other cases the TMS9900 produces much more efficient and smaller code. The Z80 Floating Point Math Package that I have ported to the TMS9900 is probably about the same size but I will do a check. Looks like it is all working now, but your post helped me quite a bit.
  8. Yes, I should have specified that. R5 to R7 (Upper Byte) represent a Floating Point Mantissa and the Lower byte of R7 the Exponent, that is why I only needed the SB for the R7 operation. So R5 is MS and R7 LS
  9. I know this is way out of date, but it helped me sort out some frustrating issues I had when carrying out some 40 bit subtraction and addition. The lesson I learnt is that you can't rely on the Carry Flag when performing arithmetic larger than 16 bits. The most reliable method I found was to use the overflow for arithmetic functions and carry for carry over to the next register. For example: ; ; ;Subtract 40 bit Destination (R5,R6,R7)from another 40 bit Source (R1,R2,R3). ; ; SUBAC: CLR R0 SB R3,R7 JNO SAC1 INC R2 ;Add carry bit JNC SAC1 INC R1 ;Add carry bit JNC SAC1 SETO R0 ;Carry to AC has occured from R5 ; ; Now subtract the registers pairs 6 and 5 ; SAC1: S R2,R6 JNO SAC2 INC R1 JNC SAC2 SETO R0 ;Carry to AC has occured from R5 SAC2: S R1,R5 ; JNO SAC3 SETO R0 SAC3: INC R0 ;Set the carry flag if carry occured RET
  10. Sure (sorry for the late response) a link to an old page is here http://itech.net.au/tms9900/ however I am trying to move most of the source now to Githun https://github.com/adel314?tab=repositories. I am also currently finalising a Floating Point Package based on 48 bit floating point numbers from Math48 package by Anders Hejlsberg. By the way, I am not sure if you are aware but a very powerful disassembler that has proved helpful in debugging is also on Github at https://github.com/jedimatt42/9900dis/tree/master/src/disassem
  11. Hello Stuart and thankyou very much for your taking the time have a look at this. My tests were carried out within a larger programme and the testing was a little ad hoc so I have taken the time code up your example and to add all three instructions. And so, this is where I look silly! Yes they do work, so I can only assume that when I was testing them in my original code that they were failing due to another issue - which I discovered only yesterday (the dirty details as that I had an instruction of the form MOV @*R4,R0 which my assembler coded as indirect but allowed and the symbolic address which caused a misalignment of PC - and this very likely caused the issue) Anyway, you are correct and the instructions do work as intended (Listing Attached with results) - thankyou. Alex R0 EQU 0 R1 EQU 1 R2 EQU 2 R3 EQU 3 R4 EQU 4 R8 EQU 8 SL EQU 9 SP EQU 10 WP EQU 13 R11 EQU 11 DXOP CALL,6 DXOP RET,7 DXOP PUSH,8 DXOP POP,9 DXOP WHEX,10 DXOP WRITE,12 ;WRITE CHAR IN MSB DXOP MESG,14 ;OUTPUT NULL TERMINATED MESSAG MONITOR EQU 0E600H AORG 8000H ;Assemble at the bottom of RAM. START LWPI WS ;Set workspace. BLWP @MONITOR CLR R3 JMP BYPASS ; DATA 0C0AH ;TCMB (Test and Clear Memory Bit) opcode. ; DATA >0C0B ;TSMB (Test and Set Memory Bit) opcode. ; DATA 01A3H ;Source operand in binary 000000 0110 10 0011 = bit displacement 6, indexed R3. ; DATA TSTVAL ; ;TEST TCMB BYPASS TCMB @TSTVAL(R3),6 JNE BY1 BL @BITHIGH JMP BY1+4 BY1: MESG @BLTXT BL @PRNTRLT ;TEST TSMB TEST2: TSMB @TSTVAL(R3),6 JNE T2A BL @BITHIGH JMP T2A+4 T2A: MESG @BLTXT BL @PRNTRLT ;TEST TB TEST3: TMB @TSTVAL(R3),6 JNE T3A BL @BITHIGH JMP T3A+4 T3A: MESG @BLTXT BL @PRNTRLT B @0F000H ;Return to monitor. BITHIGH MESG @BHTXT PRNTRLT MESG @CRLF ;Print result value. WHEX @TSTVAL MESG @CRLF RT Results are below >> TMS9900 MONITOR V2.1 < > >8000G BIT IS HIGH 0000 0000 BIT IS LOW 0200 BIT IS HIGH 0200 0200
  12. Yes, I did and I think it did work in reverse but the TCMB and TSMB just failed to work under any condition - so all that has done is dented my confidence in these instructions and have decided to abandon them. Initially I was hoping that I had misinterpreted the opcode and method but after reading a TMS99000 manual that I found on this site it appears that my coding in the assembler was correct.
  13. The one I have looks okay it is clearly labelled TMS99105A JDL. When I received the manual - stapled on the rear cover was the ERRATA sheet (attached) which only covers a hardware error for the MPY instruction but it has made me think that there were probably other problems. I only came across the TMB type instructions recently as this has been the first time I have tried to use them - I still have some hair left ! By the way, I notice that the ERRATA note also refers to the 99105,99110 and 99105A as having the bug.
  14. Thanks Mathew180 - yes your interpretation is correct, and I do have RAM at 1000H. I built a SBC around the TMS99105 in the late 80s and have just woken it up and am writing an OS for it - it has a full 64K (32k Words) and I intend to expand it once I have everything running. I have been doing a great many tests against my original TMS99105A which was marked "X for experimental" so thinking that could have been behind it, I purchased another CPU on ebay and that has the same issue. What I am beginning to think is that it may be something to do with the BST1 to BST3 coding - but I am guessing. If as you say the implementation on the chip is correct I am going to assume that and avoid the instructions. 😞 Thanks again
  15. I was wondering if anyone with a TMS99000 based system has tested the TMB, TCMB and TSMB instructions on a TMS99105A? I have a project where they would be very useful if I could get them to work and was looking for confirmation that they were actually implemented correctly on the TMS99105. _ifix:: ifix:: 0398 02AD STWP WP ;;;;;;;;;;;;;;;;;;;;;;; 1000 BIND: EQU 1000H 039A 04C3 CLR R3 039C 0204 FFFF LI R4,0FFFFH 03A0 C804 1000 MOV R4,@BIND 03A4 0C09 01A3 TMB @BIND(R3),6 03A8 1000 03AA 1302 JEQ BIND2 03AC 2E84 WHEX R4 03AE 2DC0 RET 03B0 2E83 BIND2: WHEX R3 03B2 2DC0 RET ;;;;;;;;;;;;;;;;; The code running of the code behaves which leads me to suppose that the OPCODES are recognised but the ST2 bit appears to the opposite of what is in the manual that I have. Here is a test that prints out "FFFF" when according to the data manual it should print out "0000" Any help would be greatly appreciated. Thanks Alex
  • Create New...