Jump to content
IGNORED

TMS9900 CPU core creation attempt


speccery

Recommended Posts

 

I should have known better, thanks Stuart! Once again you've already done what I was looking for, this seems perfect! :)

I am running out of time today on this project, need to continue tomorrow, first with your cartridge.

Just for CLARIFICATION I did not post DISASSEMBLY of GROM and XB ROMs of XB.

 

This is the ORIGINAL GROM and ROM code from Texas Instruments, now the changes made for RXB are listed.

 

I did not remove any original code it is commented out and I post * RXB PATCH CODE * for places it was replaced

  • Like 2
Link to comment
Share on other sites

Well that was an interesting debugging session! At the end I understood that what I thought being the problem in computing subtraction incorrectly, the actual problem manifests itself in printing (and elsewhere too). Here is the problem under extended Basic, and below the explanation how I got there. I still don't know what is the offending CPU instruction, but I am getting forward.

 

Test program under extended Basic

 

The process how I found the problem was an interesting feature set galore of the FPGA system features, and using Stuart's cool LBLA / debugger module:

 

Since I thought the problem is in the subtract operation, I studied the excellent TI Intern book based on the comment from RXB SSUB routine address. I wrote a simple Basic program:

A=1
B=2
C=A-B 

and ran this under classic99, setting breakpoints at >D74 and >FA6 to see the contents of the scratchpad memory before and after the subtraction operation when running extended Basic. (I could have determined earlier the problem cannot be in this ROM code, as it is shared with regular TI Basic, and that was working, but bear with me - these things only make sense once you know where the problem is not present).

I could see the contents of floating point accumulator at 834A (the value 1) and the argument at 835C (the value 2) and after the operation the floating point accumulator became negative. That makes sense.

 

Next I wanted to verify if this is what happens with my FPGA CPU. This is where I got to use Stuart's cartridge and some features of the FPGA system.

First, taking advantage that in the FPGA system ROM actually is RAM, I loaded Stuart's cartridge and modified system ROM to call a subroutine at the beginning of subtract operation (I added the BLWP @>1360 instruction)

Inserted BLWP @>1360 instruction at >7DC

Notice that as I had to have space for my intercepting subroutine call. I overwrote the NEG instruction at >D7C and moved the NEG @>834A instruction to the intercepted routine. I placed the subroutine at >1364, writing over cassette support code.

The code jumped to from intercept at beginning of subtract

I then did the same operation again at the end of the floating point routine, at >FA6, this time moving the instruction MOV @>834A,R1 to the interception routine.

 

The second intercept point at the end of subtract (or actually rounding)

Second intercept destination

The actual benefit of the intercept routines is that they copy the entire scratchpad memory to a safe place, before and after executing Basic ROM's floating point subtract routine respectively. The FPGA system has 1 kilobyte of scratchpad memory instead of the regular 256 bytes, so I just copied the memory from 8300 .. 83FF first to 8100..81FF and at the end to 8200..82FF.

 

After making those patches to the system ROM, I copied the modified ROM to PC's disk. I then initialized the FPGA system again, this time with the modified ROM but with extended Basic cartridge inserted instead of Stuart's cartridge. Next I again performed my subtraction in Basic. Once running that piece of Basic code, I just read back the two copies (before and after subtract) of scratchpad memory, and compared them. At this point I saw that the subtract had in fact executed correctly, and the problem manifests itself when printing negative numbers - the minus sign does not appear. The problem also occurs with other operations, since cos and sin functions also have issues.

 

I am very happy with the DMA feature of the FPGA system, as this enables me to read and write the TI clone's memory while the system is running - super handy for debugging. The same mechanism is used when the system is booted up from PC (it can also boot from flash ROM).

 

Now, after this debugging session, I know where the problem is not. Progress.

Edited by speccery
  • Like 4
Link to comment
Share on other sites

Here is a cartridge program I've been working on for validating CPU instructions. It's based on your earlier description of a program that runs through various instructions with varying inputs and check the results. It checks all combinations of the inputs 0,1,>7FFF,>8000,>AAAA,>FFFF with the following instructions: A AB ABS AI ANDI C CB CI COC CLR CZC DEC DECT DIV INC INCT INV LI MOV MOVB MPY NEG ORI S SB SETO SLA SLA0 SOC SOCB SRA SRA0 SRC SRC0 SRL SRL0 SWPB SZC SZCB XOR. The status flags are set to two known states before each test, to verify that only the proper status flags are modified. If all goes well, the display should show "OK!". For the first 24 failures, a line is printed containing: the instruction name, the first and second input, the result, the expected result, then the status flags, and finally the expected status flags. The first status flag byte is the result of the instruction after only EQ is set, and the second byte is the result after LGT AGT C OV OP are set. Instructions ending in I have the inputs swapped. Shift instructions ending in zero use the R0 register for the shift amount, otherwise are shifted by 1. I've tested Classic99 and it is ok, so it will be interesting to see how it fares on your CPU.

cputestc.bin

  • Like 2
Link to comment
Share on other sites

I tried it in MAME, and I am getting INV printouts like this (24 lines):

INV 0000 0000 FFFF FFFF 808C 809C

So that means that the status register differs in bit 11 (from left), where the specs say that those bits are unused and set to 0? (TMS 9900 Microprocessor Manual, p. 21, section 3.4)

cputest.rpk

Link to comment
Share on other sites

I tried it in MAME, and I am getting INV printouts like this (24 lines):

INV 0000 0000 FFFF FFFF 808C 809C

So that means that the status register differs in bit 11 (from left), where the specs say that those bits are unused and set to 0? (TMS 9900 Microprocessor Manual, p. 21, section 3.4)

It's not bit 11, it's actually the leftmost 8 bits of the status word twice, so it's bit 3 (from left) which means MAME INV is clearing the C status flag. The Editor Assembler manual says only L> A> and EQ bits are modified by INV. The reason I have two sets of status bits is because before the instruction is executed the status bits are set to EQ only, and then again with L> A> C OV P. That way I can check if bits are being set or cleared properly, that you might not catch with a single test. Does it print OK on a real console?

Edited by PeteE
Link to comment
Share on other sites

OK, understood. You're certainly right, this is a bug. I fixed it; also got an issue with OV bit set by SRA, also fixed. Thank you for this tool!

 

But what is this here:

 

 

SLA0 0000 8000 0000 0000 2024 282C

 

This means that R0 is used for shifting, but 24 = 00100100 (LAECOPX-) means that parity is expected to be set (where MAME keeps it reset)?

  • Like 1
Link to comment
Share on other sites

I really should have tested this on a real console again before posting the binary. The shift by R0 was one of the tests I added afterward. This could possibly be a bug in Classic99. I'm at work now, but I can try it later at home.

 

EDIT: Not a bug in Classic99, Tursi did his homework :D

Edited by PeteE
  • Like 1
Link to comment
Share on other sites

 

SLA0 0000 8000 0000 0000 2024 282C

This means that R0 is used for shifting, but 24 = 00100100 (LAECOPX-) means that parity is expected to be set (where MAME keeps it reset)?

 

Edit: actually the expected bits (282C) are right word, so it expects OV to be set (since 8000 shifted by 16 overflows). Looking at the MAME source, it seems like it should be triggering the overflow. The P flag is preserved, as it should be.

 

 

Effectively,

LI R0,>0000
LI R1,>8000
SLA R1,0
Source code, if it helps:

 

 

       AORG >6000         ; Cartridge header in all banks
HEADER
       BYTE >AA     ; Standard header
       BYTE >01     ; Version number 1
       BYTE >01     ; Number of programs (optional)
       BYTE >00     ; Reserved (for FG99 this can be G,R,or X)
       DATA >0000   ; Pointer to power-up list
       DATA PRGLST  ; Pointer to program list
       DATA >0000   ; Pointer to DSR list
       DATA >0000   ; Pointer to subprogram list

PRGLST DATA >0000   ; Next program list entry
       DATA START   ; Program address
       BYTE CRTNME-CRTNM       ; Length of name
CRTNM  TEXT 'CPU TEST'
CRTNME
TXTOK  TEXT "OK!"
       EVEN


VDPWD  EQU  >8C00             ; VDP write data
VDPWA  EQU  >8C02             ; VDP set read/write address
VDPRD  EQU  >8800             ; VDP read data (don't forget NOP after address)
VDPSTA EQU  >8802             ; VDP status
VDPWM  EQU  >4000             ; VDP address write mask
VDPRM  EQU  >8000             ; VDP address register mask


INPUTS DATA 0,1,>7FFF,>8000,>AAAA,>FFFF
INPUTE

START  LIMI 0
       LWPI >8300

       LI R0,VDPWM+>800+(32*
       MOVB @>8301,@VDPWA
       MOVB R0,@VDPWA

       LI R0,>06B4   ; regular upper case chars in grom
       MOVB R0,@>9C02
       SWPB R0
       MOVB R0,@>9C02
       LI R2,(96-32)
       LI R3,>9800  ; grom read data port
       LI R4,VDPWD  ; vdp write data port
!      MOVB *R3,*R4
       MOVB *R3,*R4
       MOVB *R3,*R4
       MOVB *R3,*R4
       MOVB *R3,*R4
       MOVB *R3,*R4
       MOVB *R3,*R4
       CLR *R4
       DEC R2
       JNE -!
       
       LI R0,XO8320
       LI R1,>8320
       LI R2,(F_END-F_AI)/2
!      MOV *R0+,*R1+
       DEC R2
       JNE -!


       LI R0,>01F0 + VDPRM  ; Set reg 1 to F0
       MOVB @>8301,@VDPWA
       MOVB R0,@VDPWA

       LI R0,>07F4 + VDPRM  ; Set reg 7 to F4
       MOVB @>8301,@VDPWA
       MOVB R0,@VDPWA

       LI R0,VDPWM
       MOVB @>8301,@VDPWA
       MOVB R0,@VDPWA


       LI R15,>A000  ; 32 high mem
       LI R9,MEMDMP  ; mem dump from classic99
       LI R10,FUNCS
       LI R8,24
       CLR R12

; test function in R7
TEST
       MOV *R10+,R7
       JEQ DONE

       LI R13,INPUTS
!      LI R14,INPUTS
!      MOV *R13,R0   ; get first operand
       MOV *R14,R1  ; get second operand

       LI R2,>A000
       AB R2,R2   ; set status LGT AGT C OV P

       BL *R7
       STST R5    ; get status flags

       MOV *R13,R0   ; get first operand
       MOV *R14+,R1  ; get second operand

       CLR R2
       AB R2,R2   ; set status EQ

       BL *R7
       STST R3    ; get status flags
       MOVB R5,@>8307
       ANDI R3,>FCFC

       MOV R1,*R15+
       MOV R3,*R15+

       MOV *R9+,R2  ; get expected result
       MOV *R9+,R4  ; get expected flags

       C R1,R2    ; compare results
       JNE FAIL
       C R3,R4    ; compare status flags
       JNE FAIL

RESUME
       CI R14,INPUTE
       JNE -!
       INCT R13
       CI R13,INPUTE
       JNE -!!
       JMP TEST

DONE
       CI R8,24
       JNE DONE2
       LI R0,TXTOK
       LI R15,VDPWD
       MOVB *R0+,*R15
       MOVB *R0+,*R15
       MOVB *R0+,*R15
DONE2
       LIMI 2
!
       JMP -!


FAIL   ; R0=operand1 R1=result R2=exp result R3=flags R4=exp flags
       MOV R8,R8
       JEQ RESUME  ; don't print if counter is zero
       DEC R8
       LI R5,VDPWD

       MOV R10,R11
       AI R11,-FUNCS-2
       SLA R11,1
       AI R11,NAMES
       MOVB *R11+,*R5
       MOVB *R11+,*R5
       MOVB *R11+,*R5
       MOVB *R11+,*R5

       BL @PRHEX  ; input 1
       
       DECT R14
       MOV *R14+,R0
       BL @PRHEX  ; input 2
       
       MOV R1,R0
       BL @PRHEX  ; result
       
       MOV R2,R0
       BL @PRHEX  ; expected result

       LI R6,>2000
       MOVB R6,*R5

       MOV R3,R0
       BL @PRHEX  ; flags

       MOV R4,R0
       BL @PRHEX  ; expected flags

       LI R6,>2000
       MOVB R6,*R5
       MOVB R6,*R5
       MOVB R6,*R5
       MOVB R6,*R5
       MOVB R6,*R5

       JMP RESUME

PRHEX ; print R0 in hex, modifies R6
       LI R6,>2000
       MOVB R6,*R5

       MOV R0,R6
       SRL R6,4
       ANDI R6,>f00
       CI R6,>a00
       JL !
       AI R6,('A'-'0'->A)*>100
!      AI R6,('0')*>100
       MOVB R6,*R5

       MOV R0,R6
       ANDI R6,>f00
       CI R6,>a00
       JL !
       AI R6,('A'-'0'->A)*>100
!      AI R6,('0')*>100
       MOVB R6,*R5

       MOV R0,R6
       SLA R6,4
       ANDI R6,>f00
       CI R6,>a00
       JL !
       AI R6,('A'-'0'->A)*>100
!      AI R6,('0')*>100
       MOVB R6,*R5

       MOV R0,R6
       SWPB R6
       ANDI R6,>f00
       CI R6,>a00
       JL !
       AI R6,('A'-'0'->A)*>100
!      AI R6,('0')*>100
       MOVB R6,*R5
       
       RT
       
       
FUNCS  DATA F_A, F_AB, F_ABS, F_AI, F_ANDI, F_C, F_CB, F_CI, F_COC, F_CLR, F_CZC, F_DEC, F_DECT
       DATA F_DIV, F_INC, F_INCT, F_INV, F_LI, F_MOV, F_MOVB, F_MPY, F_NEG, F_ORI, F_S, F_SB
       DATA F_SETO, F_SLA, F_SLA0, F_SOC, F_SOCB, F_SRA, F_SRA0, F_SRC, F_SRC0, F_SRL, F_SRL0
       DATA F_SWPB, F_SZC, F_SZCB, F_XOR, 0
       
NAMES  TEXT "A   AB  ABS AI  ANDIC   CB  CI  COC CLR CZC DEC DECTDIV INC INCTINV LI  MOV MOVB"
       TEXT "MPY NEG ORI S   SB  SETOSLA SLA0SOC SOCBSRA SRA0SRC SRC0SRL SRL0SWPBSZC SZCBXOR "

F_A    A  R0,R1
       RT
F_AB   AB R0,R1
       RT
F_ABS  ABS R1
       RT
F_C    C  R0,R1
       RT
F_CB   CB R0,R1
       RT
F_COC  COC R0,R1
       RT
F_CLR  CLR R1
       RT
F_CZC  CZC R0,R1
       RT
F_DEC  DEC R1
       RT
F_DECT DECT R1
       RT
F_DIV  DIV R1,R0
       RT
F_INC  INC R1
       RT
F_INCT INCT R1
       RT
F_INV  INV R1
       RT
F_MOV  MOV R0,R1
       RT
F_MOVB MOVB R0,R1
       RT
F_MPY  MPY R1,R0
       RT
F_NEG  NEG R1
       RT
F_S    S R0,R1
       RT
F_SB   SB R0,R1
       RT
F_SETO SETO R1
       RT
F_SLA  SLA R1,1
       RT
F_SLA0 SLA R1,0
       RT
F_SOC  SOC R0,R1
       RT
F_SOCB SOCB R0,R1
       RT
F_SRA  SRA R1,1
       RT
F_SRA0 SRA R1,0
       RT
F_SRC  SRC R1,1
       RT
F_SRC0 SRC R1,0
       RT
F_SRL  SRL R1,1
       RT
F_SRL0 SRL R1,0
       RT
F_SWPB SWPB R1
       RT
F_SZC  SZC R0,R1
       RT
F_SZCB SZCB R0,R1
       RT
F_XOR  XOR R0,R1
       RT


       
       
MEMDMP BCOPY "99test3.dat"

XO8320
       XORG >8320
F_AI
       MOV R0,@!+2
!      AI R1,0
       RT
F_ANDI
       MOV R0,@!+2
!      ANDI R1,0
       RT
F_CI
       MOV R0,@!+2
!      CI R1,0
       RT
F_LI
       MOV R0,@!+2
!      LI R1,0
       RT
F_ORI
       MOV R0,@!+2
!      ORI R1,0
       RT
F_END

 

Edited by PeteE
Link to comment
Share on other sites

What does the "!" label mean? (Mind that I am only using Editor/Assembler.)

 

I can try to step forward in MAME to the execution of that instruction.

 

(BTW, setting status bits could be easier with RTWP (load the status value into R15, R13 = current WS, R14 = $+2). The 9995 has a LST operation.)

Link to comment
Share on other sites

What does the "!" label mean? (Mind that I am only using Editor/Assembler.)

Oh sorry, that's a local label, supported only by Ralph's XDT assembler.

 

The breakpoint is at >632A.

 

Edit:

 

OK now. While fixing the last issue, I unintentionally changed the semantics of the OV in SLA. Now MAME delivers "OK!"

Oh cool, glad I could help make MAME better. Here's hoping it can help Speccery too.

Edited by PeteE
  • Like 1
Link to comment
Share on other sites

This is one of those bugs that only show up when your (spaceship | MunchMan | laser beam | medical probe) is at a position in the game that has common divisors with the sum of my birth year and my car license plate. (In other words: almost never, and when it does, you have absolutely no clue what has happened.)

 

Some years ago, a bug that was also related to the overflow status bit made it impossible to cure a patient in Microsurgeon because the game always started with the deceased patient. Now try to find out why everything else works, just not this game.

  • Like 4
Link to comment
Share on other sites

Here is a cartridge program I've been working on for validating CPU instructions. It's based on your earlier description of a program that runs through various instructions with varying inputs and check the results. It checks all combinations of the inputs 0,1,>7FFF,>8000,>AAAA,>FFFF with the following instructions: A AB ABS AI ANDI C CB CI COC CLR CZC DEC DECT DIV INC INCT INV LI MOV MOVB MPY NEG ORI S SB SETO SLA SLA0 SOC SOCB SRA SRA0 SRC SRC0 SRL SRL0 SWPB SZC SZCB XOR. The status flags are set to two known states before each test, to verify that only the proper status flags are modified. If all goes well, the display should show "OK!". For the first 24 failures, a line is printed containing: the instruction name, the first and second input, the result, the expected result, then the status flags, and finally the expected status flags. The first status flag byte is the result of the instruction after only EQ is set, and the second byte is the result after LGT AGT C OV OP are set. Instructions ending in I have the inputs swapped. Shift instructions ending in zero use the R0 register for the shift amount, otherwise are shifted by 1. I've tested Classic99 and it is ok, so it will be interesting to see how it fares on your CPU.

 

 

Thanks, this is awesome and extremely helpful to have an independent piece of verification code! I've not had time during the week to test this, but I am looking forward to doing so this evening. Hopefully something shows up immediately :)

 

Also your testing methodology is better than my test code, I should also test the instructions twice, to make sure the flags go both ways properly. Thus I can improve my test coverage by making a simple modification. Perhaps I should also work on the test code to make it a cartridge, could be useful to others too.

  • Like 2
Link to comment
Share on other sites

The test suite found an error in js99er.net. However, it was not the tested instruction (A) that didn't work but the instruction to clear the flag before the test (AB) that didn't clear the parity flag. Just something to be aware of if you get any errors.

  • Like 5
Link to comment
Share on other sites

It was great to be able to use PeteE's software, I found and fixed two bugs:

1. Despite my "testing" there still was a bug with the treatment of ST1 (A> flag) with the ABS instruction. The processing just lacked completely the special case that ABS instruction sets ST1 based on the source argument.

2. SLA0 did not set overflow flag properly if shift count was greater than one.

 

Fixing bug 1 got extended Basic fixed! So now I could resume what I was actually trying to implement, read access to the serial flash ROM chip. To my delight the code I had writing worked, and I was able to access the serial flash ROM from Basic with a series of call load(...) and call peek(...) statements. I wish the Basic had direct support for hexadecimal numbers, both input and output. The Oric Atmos Basic features these and also DOKE and DEEK operations, which enable peeks and pokes but with 16-bit values...

 

Anyway, with the bugs fixed, all the test cases pass now. It's great that this test is now also very easy to repeat whenever the CPU is updated.

  • Like 5
Link to comment
Share on other sites

I wish the Basic had direct support for hexadecimal numbers, both input and output.

 

It's my job to say Forth has been used to wring out new hardware for 50 years for this very reason. HEX OCTAL BINARY, whatever radix you need. ;-)

 

There is now also the Hayes Tester syntax that lets you test code even while it's being compiled if you choose that.

I think it could be used for a CPU instruction set as well.

However writing the test cases and all the corner cases is still diligent work.

 

Anyway I guess it's all moot now since you have it working. Congratulations!

\ test example.  BL should result in HEX 20 output to the stack
HEX
T{ BL -> 20 }T

\ tests for AND operation
T{ 0 0 AND -> 0 }T 
T{ 0 1 AND -> 0 }T 
T{ 1 0 AND -> 0 }T 
T{ 1 1 AND -> 1 }T
T{ 0 INVERT 1 AND -> 1 }T 
T{ 1 INVERT 1 AND -> 0 }T
  • Like 3
Link to comment
Share on other sites

It's my job to say Forth has been used to wring out new hardware for 50 years for this very reason. HEX OCTAL BINARY, whatever radix you need. ;-)

 

Thanks, that is a good comment. I have also used Forth to bring up hardware - the last project of this type was porting the J1 CPU for the BlackIce-II FPGA board. The J1 is essentially a Forth CPU. I'm tempted to add a co-processor system to my TI-99/4A FPGA system with this CPU. It is very compact and very fast. You probably already know about it. This could be used for example to aid debugging, to monitor TI-99/4A signals etc. To make it truly useful it would need to have some capability to interface with the TI's peripherals. On the other hand my next goal is to make my system more accessible by porting it to other low-cost and widely available boards. I'm trying to resist feature creep until then.

https://excamera.com/sphinx/fpga-j1.html

Link to comment
Share on other sites

 

Thanks, that is a good comment. I have also used Forth to bring up hardware - the last project of this type was porting the J1 CPU for the BlackIce-II FPGA board. The J1 is essentially a Forth CPU. I'm tempted to add a co-processor system to my TI-99/4A FPGA system with this CPU. It is very compact and very fast. You probably already know about it. This could be used for example to aid debugging, to monitor TI-99/4A signals etc. To make it truly useful it would need to have some capability to interface with the TI's peripherals. On the other hand my next goal is to make my system more accessible by porting it to other low-cost and widely available boards. I'm trying to resist feature creep until then.

https://excamera.com/sphinx/fpga-j1.html

 

Cool. I love that J1 processor.

 

For those who don't know about J1, imagine a subroutine call that takes 1 clock cycle and a return that takes 0 clocks.

 

One of my thoughts, although I don't have any knowledge of Verilog is that Forth CPUs would benefit from having a workspace register to

assist multitasking. The Forth stacks typically are in very fast on chip ram, but if you want to change tasks it can be awkward swapping the stacks (ie registers) in/out of conventional memory. So... if there were larger memory spaces available for a number of tasks and a workspace register, the chip could have fast context switching albeit for a finite number of tasks, which is typically ok for an embedded application.

 

You are probably one of the few people in the world who know about FPGA 9900 and J1. :-)

 

Is there a repository of your code for the J1->BlackIce project?

Edited by TheBF
  • Like 1
Link to comment
Share on other sites

Cool. I love that J1 processor.

 

For those who don't know about J1, imagine a subroutine call that takes 1 clock cycle and a return that takes 0 clocks.

 

One of my thoughts, although I don't have any knowledge of Verilog is that Forth CPUs would benefit from having a workspace register to

assist multitasking. The Forth stacks typically are in very fast on chip ram, but if you want to change tasks it can be awkward swapping the stacks (ie registers) in/out of conventional memory. So... if there were larger memory spaces available for a number of tasks and a workspace register, the chip could have fast context switching albeit for a finite number of tasks, which is typically ok for an embedded application.

 

You are probably one of the few people in the world who know about FPGA 9900 and J1. :-)

The J1 implements its stacks as two huge shift registers, where each shift operation is a shift by word length, typically 16 or 32 bits. The stacks are not deep, they're for the 16-bit version by default 15 deep for data stack and 17 for the return stack. So these stacks are implemented in the FPGA logic fabric, not in block memory. This also means that there are no stack pointers, at least for the J1A version. So you don't know how deep you're in the stacks... The source code for J1A is about 130 lines of Verilog. It is tiny. It is inspired by the Novic NC4016 to my understanding. The J1 is an awesome project, and it comes with Swapforth already implemented. The basic J1 system for the BlackIce takes 1072 logic cells, so about one eight of the total capacity.

It is not only that subroutine calls and pretty much every other instruction takes 1 clock cycle, you can also combine certain operations such as the subroutine return to it. Oh, and it runs at 48 MHz on the BlackIce-II. I did not try to optimize it.

I think I also ported it over to the Pepino board, as 32 bit version. Along the lines James had done his version for the Xilinx Spartan 6.

 

Is there a repository of your code for the J1->BlackIce project?

No but I guess I could set it up. I was playing with the Icestorm tools and used the J1 as the core to play with. I did not do much, my work amounted to merging the top level block from BlackIce examples with the J1. I tested it with both place-and-route tools: arcahne-pnr and the newer nextpnr. For the latter I had to study things a little to get the PLL done properly (the input clock is 100MHz, which the PLL takes to 48MHz).

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

 

How many logic cells did it take to re-create the 9900?

 

 

Sorry for the long delay in answering. I have not tested to synthesise the plain vanilla TMS9900 core without any peripherals.

 

Looking into one of the breadboard project targets on my GitHub account https://github.com/Speccery/breadboard/blob/master/bb-lx9/work/system_summary.html you can see that a minimal TMS9900 system took 1690 Xilinx Spartan 6 slice LUTs, or 29% of the XC6SLX9 chip. This system includes the TMS9900 core, 32K RAM, 32K ROM, and PNR's TMS9902 UART, all implemented using the FPGA's built-in resources. In a way this number is comparable to the 1072 logic cells for the J1 as that system also includes memory interface, some I/O and UART. However, the Spartan 6 logic core elements are much more advanced than what the Lattice ICE40HX provides, so the numbers 1690 vs 1072 are not directly comparable.

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...