Jump to content

Recommended Posts

Hi Guys.

 

Just for testing, first attempt :) and get intybasic better to know. A simple Tic-Tac-Toe game.

 

rom already more than 14k :(

 

I experienced a few weird things like:

 

wait:gosub think

 

should be changed to:

 

wait

gosub think

 

and read dont accept array.

 

read v(1)

 

should be changed to:

 

read t:v(1)=t

 

 

cb-tictactoe.rom

  • Like 1
Link to comment
https://forums.atariage.com/topic/231388-my-first-test-tic-tac-toe-with-intybasic/
Share on other sites

It looks very slick, with lots of animation. Cool!

 

 

 

Regarding size.... looking at the disassembly, it appears there are many IntyBASIC constructs that aren't code-size friendly that your Tic-Tac-Toe code has "unrolled". Obviously, I haven't seen the BASIC source, so I don't know what those are or what you wrote that triggered these. Still, there's some impressive repetitive sequences in the disassembly, such as:

        MVI     G_0138, R0                      ; 517D   0280 0138
        CMPI    #$0002, R0                      ; 517F   0378 0002
        MVII    #$FFFF, R0                      ; 5181   02B8 FFFF
        BEQ     L_5186                          ; 5183   0204 0001

        INCR    R0                              ; 5185   0008
L_5186:
        MVI     G_0138, R1                      ; 5186   0281 0138
        CMPI    #$0004, R1                      ; 5188   0379 0004
        MVII    #$FFFF, R1                      ; 518A   02B9 FFFF
        BEQ     L_518F                          ; 518C   0204 0001

        INCR    R1                              ; 518E   0009
L_518F:
        COMR    R1                              ; 518F   0019
        ANDR    R1,     R0                      ; 5190   0188
        COMR    R1                              ; 5191   0019
        XORR    R1,     R0                      ; 5192   01C8
        MVI     G_0138, R1                      ; 5193   0281 0138
        CMPI    #$0006, R1                      ; 5195   0379 0006
        MVII    #$FFFF, R1                      ; 5197   02B9 FFFF
        BEQ     L_519C                          ; 5199   0204 0001

        INCR    R1                              ; 519B   0009
L_519C:
        COMR    R1                              ; 519C   0019
        ANDR    R1,     R0                      ; 519D   0188
        COMR    R1                              ; 519E   0019
        XORR    R1,     R0                      ; 519F   01C8
        MVI     G_0138, R1                      ; 51A0   0281 0138
        CMPI    #$0008, R1                      ; 51A2   0379 0008
        MVII    #$FFFF, R1                      ; 51A4   02B9 FFFF
        BEQ     L_51A9                          ; 51A6   0204 0001

        INCR    R1                              ; 51A8   0009
L_51A9:
        COMR    R1                              ; 51A9   0019
        ANDR    R1,     R0                      ; 51AA   0188
        COMR    R1                              ; 51AB   0019
        XORR    R1,     R0                      ; 51AC   01C8
        MVI     G_0138, R1                      ; 51AD   0281 0138
        CMPI    #$000A, R1                      ; 51AF   0379 000A
        MVII    #$FFFF, R1                      ; 51B1   02B9 FFFF
        BEQ     L_51B6                          ; 51B3   0204 0001

        INCR    R1                              ; 51B5   0009
L_51B6:
        COMR    R1                              ; 51B6   0019
        ANDR    R1,     R0                      ; 51B7   0188
        COMR    R1                              ; 51B8   0019
        XORR    R1,     R0                      ; 51B9   01C8
        MVI     G_0138, R1                      ; 51BA   0281 0138
        CMPI    #$000C, R1                      ; 51BC   0379 000C
        MVII    #$FFFF, R1                      ; 51BE   02B9 FFFF
        BEQ     L_51C3                          ; 51C0   0204 0001

        INCR    R1                              ; 51C2   0009
L_51C3:
        COMR    R1                              ; 51C3   0019
        ANDR    R1,     R0                      ; 51C4   0188
        COMR    R1                              ; 51C5   0019
        XORR    R1,     R0                      ; 51C6   01C8
        MVI     G_0138, R1                      ; 51C7   0281 0138
        CMPI    #$000E, R1                      ; 51C9   0379 000E
        MVII    #$FFFF, R1                      ; 51CB   02B9 FFFF
        BEQ     L_51D0                          ; 51CD   0204 0001

        INCR    R1                              ; 51CF   0009
L_51D0:
        COMR    R1                              ; 51D0   0019
        ANDR    R1,     R0                      ; 51D1   0188
        COMR    R1                              ; 51D2   0019
        XORR    R1,     R0                      ; 51D3   01C8
        TSTR    R0                              ; 51D4   0080
        BEQ     L_51FA                          ; 51D5   0204 0023

That bit of code, which looks like it might be from some sort of IF statement OR-ing several conditions together, is 178 bytes all by itself. It looks like it's testing to see if some variable is 2, 4, 6, 8, 10, 12, or 14, if I understood the assembly correctly.

 

That could be coded more succinctly as testing whether it's greater than 1, less than 15, and if it's even. (That is, see if var AND 1 is equal to 0 or 1.)

 

The Intellivision doesn't natively support OR, so the COMR/ANDR/COMR/XORR sequence is necessary to simulate it.

 

In cases where you just care about true/false, you may be able to replace OR with + and get a code-size savings there.

 

There was another function I saw starting at $5E63 and ending at $605A (nearly 1K bytes all by itself!) that seemed to be displaying stuff to the screen. I didn't get into too much detail, but I saw several stretches of code like this that really add to the codesize:

L_6066:
        MVII    #$02B4, R0                      ; 6066   02B8 02B4
        MVO     R0,     G_033E                  ; 6068   0240 033E
        MVII    #$0005, R0                      ; 606A   02B8 0005
        MVO     R0,     G_033F                  ; 606C   0240 033F
        MVI     G_033E, R4                      ; 606E   0284 033E
        MVII    #$0000, R0                      ; 6070   02B8 0000
        XOR     G_033F, R0                      ; 6072   03C0 033F
        MVO@    R0,     R4                      ; 6074   0260
        MVII    #$00D0, R0                      ; 6075   02B8 00D0
        XOR     G_033F, R0                      ; 6077   03C0 033F
        MVO@    R0,     R4                      ; 6079   0260
        MVII    #$0140, R0                      ; 607A   02B8 0140
        XOR     G_033F, R0                      ; 607C   03C0 033F
        MVO@    R0,     R4                      ; 607E   0260
        MVII    #$01A8, R0                      ; 607F   02B8 01A8
        XOR     G_033F, R0                      ; 6081   03C0 033F
        MVO@    R0,     R4                      ; 6083   0260
        MVII    #$0168, R0                      ; 6084   02B8 0168
        XOR     G_033F, R0                      ; 6086   03C0 033F
        MVO@    R0,     R4                      ; 6088   0260
        MVII    #$0108, R0                      ; 6089   02B8 0108
        XOR     G_033F, R0                      ; 608B   03C0 033F
        MVO@    R0,     R4                      ; 608D   0260
        MVII    #$0170, R0                      ; 608E   02B8 0170
        XOR     G_033F, R0                      ; 6090   03C0 033F
        MVO@    R0,     R4                      ; 6092   0260
        MVII    #$0000, R0                      ; 6093   02B8 0000
        XOR     G_033F, R0                      ; 6095   03C0 033F
        MVO@    R0,     R4                      ; 6097   0260
        MVO@    R0,     R4                      ; 6098   0260
        MVII    #$0000, R0                      ; 6099   02B8 0000
        XOR     G_033F, R0                      ; 609B   03C0 033F
        MVO@    R0,     R4                      ; 609D   0260
        MVO@    R0,     R4                      ; 609E   0260
        MVII    #$0000, R0                      ; 609F   02B8 0000
        XOR     G_033F, R0                      ; 60A1   03C0 033F
        MVO@    R0,     R4                      ; 60A3   0260
        MVO@    R0,     R4                      ; 60A4   0260
        MVII    #$0000, R0                      ; 60A5   02B8 0000
        XOR     G_033F, R0                      ; 60A7   03C0 033F
        MVO@    R0,     R4                      ; 60A9   0260
        MVO@    R0,     R4                      ; 60AA   0260
        MVII    #$0000, R0                      ; 60AB   02B8 0000
        XOR     G_033F, R0                      ; 60AD   03C0 033F
        MVO@    R0,     R4                      ; 60AF   0260
        MVO     R4,     G_033E                  ; 60B0   0244 033E
        MVII    #$02C8, R0                      ; 60B2   02B8 02C8
        MVO     R0,     G_033E                  ; 60B4   0240 033E
        MVII    #$0005, R0                      ; 60B6   02B8 0005
        MVO     R0,     G_033F                  ; 60B8   0240 033F
        MVI     G_033E, R4                      ; 60BA   0284 033E
        MVII    #$0000, R0                      ; 60BC   02B8 0000
        XOR     G_033F, R0                      ; 60BE   03C0 033F
        MVO@    R0,     R4                      ; 60C0   0260
        MVII    #$00D0, R0                      ; 60C1   02B8 00D0
        XOR     G_033F, R0                      ; 60C3   03C0 033F
        MVO@    R0,     R4                      ; 60C5   0260
        MVII    #$0118, R0                      ; 60C6   02B8 0118
        XOR     G_033F, R0                      ; 60C8   03C0 033F
        MVO@    R0,     R4                      ; 60CA   0260
        MVII    #$0180, R0                      ; 60CB   02B8 0180
        XOR     G_033F, R0                      ; 60CD   03C0 033F
        MVO@    R0,     R4                      ; 60CF   0260
        MVII    #$01A8, R0                      ; 60D0   02B8 01A8
        XOR     G_033F, R0                      ; 60D2   03C0 033F
        MVO@    R0,     R4                      ; 60D4   0260
        MVII    #$0000, R0                      ; 60D5   02B8 0000
        XOR     G_033F, R0                      ; 60D7   03C0 033F
        MVO@    R0,     R4                      ; 60D9   0260
        MVO@    R0,     R4                      ; 60DA   0260
        MVII    #$0000, R0                      ; 60DB   02B8 0000
        XOR     G_033F, R0                      ; 60DD   03C0 033F
        MVO@    R0,     R4                      ; 60DF   0260
        MVO@    R0,     R4                      ; 60E0   0260
        MVII    #$0000, R0                      ; 60E1   02B8 0000
        XOR     G_033F, R0                      ; 60E3   03C0 033F
        MVO@    R0,     R4                      ; 60E5   0260
        MVO@    R0,     R4                      ; 60E6   0260
        MVII    #$0000, R0                      ; 60E7   02B8 0000
        XOR     G_033F, R0                      ; 60E9   03C0 033F
        MVO@    R0,     R4                      ; 60EB   0260
        MVO@    R0,     R4                      ; 60EC   0260
        MVII    #$0000, R0                      ; 60ED   02B8 0000
        XOR     G_033F, R0                      ; 60EF   03C0 033F
        MVO@    R0,     R4                      ; 60F1   0260
        MVO@    R0,     R4                      ; 60F2   0260
        MVII    #$0000, R0                      ; 60F3   02B8 0000
        XOR     G_033F, R0                      ; 60F5   03C0 033F
        MVO@    R0,     R4                      ; 60F7   0260
        MVO     R4,     G_033E                  ; 60F8   0244 033E
        MVII    #$02DC, R0                      ; 60FA   02B8 02DC
        MVO     R0,     G_033E                  ; 60FC   0240 033E
        MVII    #$0005, R0                      ; 60FE   02B8 0005
        MVO     R0,     G_033F                  ; 6100   0240 033F
        MVI     G_033E, R4                      ; 6102   0284 033E
        MVII    #$0000, R0                      ; 6104   02B8 0000
        XOR     G_033F, R0                      ; 6106   03C0 033F
        MVO@    R0,     R4                      ; 6108   0260
        MVO@    R0,     R4                      ; 6109   0260
        MVII    #$0120, R0                      ; 610A   02B8 0120
        XOR     G_033F, R0                      ; 610C   03C0 033F
        MVO@    R0,     R4                      ; 610E   0260
        MVII    #$0190, R0                      ; 610F   02B8 0190
        XOR     G_033F, R0                      ; 6111   03C0 033F
        MVO@    R0,     R4                      ; 6113   0260
        MVII    #$0108, R0                      ; 6114   02B8 0108
        XOR     G_033F, R0                      ; 6116   03C0 033F
        MVO@    R0,     R4                      ; 6118   0260
        MVII    #$01B8, R0                      ; 6119   02B8 01B8
        XOR     G_033F, R0                      ; 611B   03C0 033F
        MVO@    R0,     R4                      ; 611D   0260
        MVII    #$0000, R0                      ; 611E   02B8 0000
        XOR     G_033F, R0                      ; 6120   03C0 033F
        MVO@    R0,     R4                      ; 6122   0260
        MVO@    R0,     R4                      ; 6123   0260
        MVII    #$0000, R0                      ; 6124   02B8 0000
        XOR     G_033F, R0                      ; 6126   03C0 033F
        MVO@    R0,     R4                      ; 6128   0260
        MVO@    R0,     R4                      ; 6129   0260
        MVII    #$0000, R0                      ; 612A   02B8 0000
        XOR     G_033F, R0                      ; 612C   03C0 033F
        MVO@    R0,     R4                      ; 612E   0260
        MVO@    R0,     R4                      ; 612F   0260
        MVII    #$0000, R0                      ; 6130   02B8 0000
        XOR     G_033F, R0                      ; 6132   03C0 033F
        MVO@    R0,     R4                      ; 6134   0260
        MVO@    R0,     R4                      ; 6135   0260
        MVII    #$0000, R0                      ; 6136   02B8 0000
        XOR     G_033F, R0                      ; 6138   03C0 033F
        MVO@    R0,     R4                      ; 613A   0260
        MVO@    R0,     R4                      ; 613B   0260
        MVO     R4,     G_033E                  ; 613C   0244 033E

I don't know what that code does—maybe you can work it out by looking at the listing file generated by AS1600—but I get the feeling a loop might help here, or DATA statements, or a combination of the two.

I'm willing to bet there are a LOT of PRINT statements in the code. I've noticed they really bulk up the final ROM size. I haven't spent much time figuring out what they're compiled to.

 

In terms of wait:gosub - the compiler is interpreting your wait: as a label. I'm not a fan of this either, but to be honest there isn't really a reason to start a line like this anyway. The : syntax to put multiple statements on a single line is only really needed after an IF statement. Otherwise you're simply using it to save whitespace, which is unnecessary.

 

Nice and fast interface regardless. It looks like you've developed something of a decision tree based on how long the computer "thinks". That is the kind of thing that can also bulk up code, depending on how you've implemented it. Be VERY careful if you use recursion for this; the INTV stack is not terribly deep (although Tic Tac Toe doesn't have a very deep game tree anyway...).

I'm willing to bet there are a LOT of PRINT statements in the code. I've noticed they really bulk up the final ROM size. I haven't spent much time figuring out what they're compiled to.

 

Indeed, that seems to be the case. Here's a simple test I did, printing "Hello Mudda! Hello Fadda!" (from the going to camp song)

.

	;     PRINT AT 0,  "Hello Mudda!"
	MVII #512,R0
	MVO R0,_screen
	MVI _screen,R4
	MVII #320,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #552,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #608,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO@ R0,R4
	MVII #632,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #0,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #360,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #680,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #544,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO@ R0,R4
	MVII #520,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #8,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO R4,_screen
	;     PRINT AT 20, "Hello Fadda!"
	MVII #532,R0
	MVO R0,_screen
	MVI _screen,R4
	MVII #320,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #552,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #608,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO@ R0,R4
	MVII #632,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #0,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #304,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #520,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #544,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO@ R0,R4
	MVII #520,R0
	XOR _color,R0
	MVO@ R0,R4
	MVII #8,R0
	XOR _color,R0
	MVO@ R0,R4
	MVO R4,_screen

.

Open-coding the print like this will always be faster than calling a subroutine, but it will also be much larger.

 

For PRINT specifically, the code generator could be a little smarter about register usage, loading _color once and putting the encoded string data in a data section of some sort, for example, even if it doesn't call a subroutine. Maybe a 1.0 wishlist feature?

 

For example, the PRINT "Hello Fadda!" above could reduce to this, and be both smaller and faster and still open-coded. It's smaller owing to loading _color once, and using a very simple XOR trick:

.

    MVII #532,R4
    MVII #S1,R5
    MVI  _color,R0
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    XOR@ R5,R0
    MVO@ R0,R4
    MVO R4,_screen
    B L1
S1: DECLE 320,552 XOR 320,608 XOR 552,632 XOR 608,0 XOR 632
    DECLE 304 XOR 0,520 XOR 304,544 XOR 520,520 XOR 544,8 XOR 520
L1:

.

With that change it went from 120 bytes down to 84 bytes for PRINT "Hello Fadda!", almost 1/3rd smaller. It would get smaller still if it output the DECLE statements at the end so it could avoid the branch-around. That would save 4 bytes. If IntyBASIC built up a simple "string table" and output it at the end of code generation, that would suffice.

 

And it would get much, much smaller if IntyBASIC just issued a call to a print function to print the string, although it would get a little slower.

 

One side note: I noticed IntyBASIC does optimize printing multiple consecutive characters that are the same by just issuing multiple MVO@ in a row. It needs to be careful not to issue too many MVO's in a row (or non-interruptible instructions in general), as too many non-interruptible instructions in a row will lead to display glitches. What we discovered during Kroz is that even as few as 45 cycles of non-interruptible instructions can, in rare cases, cause display glitches. (Usually you can get away with up to 50 or more cycles worth.)

Edited by intvnut
  • Like 1

I am sure Nanochess will continue improve the IntyBasic :) I am not into the 1600 assembler, but rather Z80 :) but as I understand it the print function is a hungry one. every single char is loaded one by one and then put to the screen. Give a bigger size. In z80 you will typical load a register with the pointer to your text, and then call a function to put it to screen, maybe the Intellivision even also have this function ?

 

My code only use a limited number of variables:

0x12B V12: RMB 1 ; A
0x12C V13: RMB 1 ; C
0x12D V1: RMB 1 ; CSC
0x12E V10: RMB 1 ; CVAL
0x12F V14: RMB 1 ; D
0x130 V4: RMB 1 ; DEMO
0x131 V3: RMB 1 ; DRAW
0x132 V15: RMB 1 ; E
0x133 V6: RMB 1 ; FIRST
0x134 V7: RMB 1 ; PL
0x135 V2: RMB 1 ; PSC
0x136 V11: RMB 1 ; PVAL
0x137 V8: RMB 1 ; S
0x138 V9: RMB 1 ; T
0x139 V5: RMB 1 ; TOMME
0x13A Q4: RMB 9 ; F
0x143 Q5: RMB 3 ; V
0x146 _SCRATCH: EQU $
from 0x100-0x12A we have Intybasic's internal memory usage, lige buffer for scroll and playing music. The trick is to try to use the same variable again and again, with out conflict.
Can intellivision handle 16 or 32 kb max rom size ?

 

I am sure Nanochess will continue improve the IntyBasic :) I am not into the 1600 assembler, but rather Z80 :) but as I understand it the print function is a hungry one. every single char is loaded one by one and then put to the screen. Give a bigger size. In z80 you will typical load a register with the pointer to your text, and then call a function to put it to screen, maybe the Intellivision even also have this function ?

 

My code only use a limited number of variables:

0x12B V12: RMB 1 ; A
0x12C V13: RMB 1 ; C
0x12D V1: RMB 1 ; CSC
0x12E V10: RMB 1 ; CVAL
0x12F V14: RMB 1 ; D
0x130 V4: RMB 1 ; DEMO
0x131 V3: RMB 1 ; DRAW
0x132 V15: RMB 1 ; E
0x133 V6: RMB 1 ; FIRST
0x134 V7: RMB 1 ; PL
0x135 V2: RMB 1 ; PSC
0x136 V11: RMB 1 ; PVAL
0x137 V8: RMB 1 ; S
0x138 V9: RMB 1 ; T
0x139 V5: RMB 1 ; TOMME
0x13A Q4: RMB 9 ; F
0x143 Q5: RMB 3 ; V
0x146 _SCRATCH: EQU $
from 0x100-0x12A we have Intybasic's internal memory usage, lige buffer for scroll and playing music. The trick is to try to use the same variable again and again, with out conflict.
Can intellivision handle 16 or 32 kb max rom size ?

 

 

I'm not sure what a 'lige' buffer is, but in any case, it looks like you aren't using very much RAM.

 

You are right, though, that the usual thing to do is to load a pointer to the string, and then call a function to display it. It's up to nanochess to improve IntyBASIC's ROM usage here if he wants to. My suggestions above are really meant for him.

 

Regarding ROM size, the short answer is: The Intellivision can use very large ROMs, up to 50K words (100K bytes) if you're careful. You can easily get to 40K words (80K bytes) without too much effort. Going beyond that requires some care.

 

 

A longer answer: You will need to insert one ASM ORG statement to go above 8K words / 16K bytes. To get to 24K words / 48K bytes, insert the statement "ASM ORG $C100" somewhere between Procedures in your program, ahead of the point where it grows beyond 8K words. To get to 40K words / 80K bytes, insert the statement "ASM ORG $8100" somewhere between procedures, ahead of the point where it grows beyond 24K words / 48K bytes.

 

Your program will have a structure like this:

.

... lots of code ...
... lots of code ... 
    ASM ORG $C100     : REM somewhere before where your program grows beyond 8K words / 16K bytes
... lots of code ... 
... lots of code ... 
    ASM ORG $8100     : REM somewhere before where your program grows beyond 24K words / 48K bytes
... lots of code ... 
... lots of code ... 

.

Beyond that, you need to know a bit more about the Intellivision memory map and how the ECS works.

 

 

And now for an even longer, more technical answer.

 

The Intellivision memory map is as follows:

  • $0000 - $003F: STIC registers
  • $0040 - $007F: Reserved for additional STIC registers, but unused
  • $0080 - $0081: Intellivoice
  • $0082 - $00DF: Intellivoice expansion port. (Never actually used for anything)
  • $00E0 - $00E2: ECS serial / cassette port
  • $00E3 - $00EF: Intellivoice expansion port. (Never actually used for anything)
  • $00F0 - $00FF: ECS sound chip (PSG)
  • $0100 - $01EF: 8-bit scratch RAM
  • $01F0 - $01FF: Master component sound chip (PSG)
  • $0200 - $02EF: BACKTAB, the character display memory
  • $02F0 - $035F: 16-bit system RAM
  • $0360 - $03FF: Unused / reserved. (On some systems, the system RAM returns garbage at these addresses.)
  • $0400 - $04FF: Intellivision II EXEC 'secret ROM'. This ROM includes the routine that makes some games purposefully incompatible with the Intellivision II.
  • $0500 - $06FF: Unused
  • $0700 - $0BFF: Intellivoice expansion port. (Never actually used for anything.)
  • $0C00 - $0FFF: Unused
  • $1000 - $1FFF: EXEC ROM
  • $2000 - $2FFF: ECS ROM, in page 1. Available for games if you take precautions.
  • $3000 - $37FF: GROM
  • $3800 - $39FF: GRAM
  • $3A00 - $3BFF: GRAM alias
  • $3C00 - $3DFF: GRAM alias
  • $3E00 - $3FFF: GRAM alias
  • $4000 - $403F: Write-only STIC register alias; $4021 is read sensitive (a read to $4021 will change STIC to color-stack mode)
  • $4000 - $47FF: ECS 8-bit RAM
  • $4800 - $4FFF: Reserved for PlayCable ROM. Available for games if you take precautions.
  • $5000 - $6FFF: Available for game ROM. $5000 is the default entry point for games.
  • $7000 - $7FFF: ECS EXEC in page 0. Available for games if you take precautions. Note: Writes to $7800 - $7FFF will alias GRAM.
  • $8000 - $803F: Write-only STIC register alias; $8021 is read sensitive (a read to $8021 will change STIC to color-stack mode)
  • $8040 - $BFFF: Available for game ROM. Note: Writes to $B800 - $BFFF will alias GRAM.
  • $C000 - $C03F: Write-only STIC register alias; $C021 is read sensitive (a read to $C021 will change STIC to color-stack mode)
  • $C040 - $DFFF: Available for game ROM.
  • $E000 - $EFFF: ECS EXEC in page 1. Available for games if you take precautions.
  • $F000 - $FFFF: Available for game ROM. Note: Writes to $F800 - $FFFF will alias GRAM.

 

Ok, that memory map is a mess. It's hard to see what memory ranges are available to games. If you ignore the ECS for a moment, you can put game ROM here:

  • $2000 - $2FFF: 4K words (8K bytes)
  • $4040 - $7FFF: 16K words (32K bytes)
  • $8040 - $BFFF: 16K words (32K bytes)
  • $C040 - $FFFF: 16K words (32K bytes)

That adds up to 52K words (104K bytes).

 

If you want to retain compatibility with the ECS, you cannot use the address range $4040 - $47FF (the ECS RAM). So that reduces your maximum ROM size to 50K words (100K bytes). You can reuse the other ROM address ranges associated with the ECS ($2xxx, $7xxx, $Exxx). Details below.

 

You may have noticed that some address ranges say they are available if you take precautions. These fall into two categories: Restrictions imposed by the Intellivision, and restrictions due to the ECS.

 

The Intellivision was designed to be expanded. The Intellivision EXEC looks for expansion ROMs at $7000 and $4800 early during its boot-up sequence. If you have ROM at either location, the EXEC will jump directly to that ROM before it has completed its initialization. So, if you program a game, and it has ROM at location $7000, the EXEC will jump directly to location $7000 early in its bootup. If your code doesn't expect that, the system will crash. The same is true for location $4800.

 

The ECS puts ROM at $2000 - $2FFF, $7000 - $7FFF, and $E000 - $EFFF. These ROMs are page-flipped (bank-switched), and can be disabled. So, it is possible to write a game that uses these address ranges, if you include code that disables the ECS ROMs. All that's required is to make three writes to locations $2FFF, $7FFF, and $EFFF with the right values ($2A5F, $7A5F and $EA5F work) to disable those ROMs near the start of your program.

 

 

By default, IntyBASIC starts your game's code at $5000. This is the Intellivision's default entry point for games. So, your game will start assembling at that address, growing upward. For games up to 8K words (16K bytes), the game will occupy the address range $5000 - $6FFF.

 

Once your game gets larger than that, if you do not include an "ASM ORG" directive anywhere, it will put code at $7000 and above. The Intellivision EXEC will see this code, and jump directly to it very early during boot. Since your code likely doesn't expect to get called at that address directly, the system will crash. So, to go larger than 8K words (16K bytes), you will need to add one or more "ASM ORG" statements in your program to avoid assembling code at $7000.

 

The easiest thing to do is to add an "ASM ORG $C100" statement to your program before the point that takes your program over the 8K word / 16K byte line. Code after that point in your program will assemble at $C100 onward, giving you access to an additional 16K words (32K bytes) of ROM at $C100 - $FFFF, on top of the 8K words (16K bytes) of ROM at $5000 - $6FFF. That gives you a total of 24K words (48K bytes) with a single extra IntyBASIC statement.

 

To get to 40K words (80K bytes), you will need a second ASM statement in your program—ASM ORG $8100—to open up the ROM at $8100 - $BFFF. You will need to add that at an appropriate point in your program to keep it from assembling beyond $FFFF. That will open up another 16K words (32K bytes) to your program.

 

To get to 44K words, 48K words and ultimately 50K words will require additional ASM ORG statements to put ROM at $2000 - $2FFF, $7100 - $7FFF and $4800 - $4FFF. Those ROM ranges are a bit more challenging to use, as they're small, and you need to be mindful of how the ECS EXEC works. If your game gets that big, I'll be happy to go into more detail.

 

 

You might wonder why I used $7100, $8100 and $C100 instead of $7001, $8040 and $C040. I have two reasons:

  • The Intellicart and CC3 map ROM in 256-word sections, and so rounding to $0100 boundaries ensures that none of your game gets mapped over one of the aliases or other ROMs (in the case of code at $7100).
  • Also, we've seen strange STIC behavior with code running near $C040 that seems to go away when we move the code to a higher address.
  • Like 3

Hi, CrazyBoss, I just took a moment to check out your game. I agree with intvnut that it looks very polished and slick, with the music and the flashy transitions. I do have some feedback though.

  • I understand why you set the play-field a bit off center during the game, but the title screen would look much better if it were aligned in the center of the screen.
  • As for the play-field during play, may I suggest moving it one or two more cards to the left? As it stands, it looks much too close to the center to feel like the text on the right pushed it off, instead of being designed that way. That will also give the status area more "breathing room."
  • Perhaps you could make the game start directly when the player presses any key, or the disc in any direction?
  • The computer is very aggressive! And it also changes its tactics often. Once I found a way to beat it, and exploited it repeatedly three times in a row. However, by the fourth time, the computer switched (perhaps randomly), and I couldn't beat it any more. It felt like it "learned," which is awesome! :)

Overall, it's a very nicely done game. It reminds me of the sort of microcomputer games that were available back in the 1980s, simple but slick. About the only thing that could improve it at this point is just embellishments in the music, sound effects, or graphics; but none of that is really necessary for this type of game.

 

Good job! :)

 

-dZ.

thanks for the feed back this game was programmed in one week, while taking care of a 1 year old baby, so it was quite limited with time. But I have programmed basic since 1987 so have coded tic-tac-toe games before.

 

this was a learning lesson for intellivision, cause collectorvision games asked me to give it a try, i might try to program other games later.

 

the game work out from some rules, so its not learning anything. It have basic rules.

thanks for the feed back this game was programmed in one week, while taking care of a 1 year old baby, so it was quite limited with time. But I have programmed basic since 1987 so have coded tic-tac-toe games before.

 

Wow, I'm impressed. It looks really slick for a game done in a week. Such is the intrepid power of IntyBASIC, I guess. :)

 

this was a learning lesson for intellivision, cause collectorvision games asked me to give it a try, i might try to program other games later.

 

Then, I cannot wait to see what you come up with for CollectorVision.

 

the game work out from some rules, so its not learning anything. It have basic rules.

 

Well, of course, I didn't really think it was learning. I just thought that the way it interacts (e.g., varying times to think, not responding identically on the same move all the time, etc.), it gives it a rather organic feel to the game, as if you were playing against a real opponent.

 

Plus the cool interface and the sound effects don't hurt either. :)

 

-dZ.

 

You might wonder why I used $7100, $8100 and $C100 instead of $7001, $8040 and $C040. I have two reasons:

  • The Intellicart and CC3 map ROM in 256-word sections, and so rounding to $0100 boundaries ensures that none of your game gets mapped over one of the aliases or other ROMs (in the case of code at $7100).
  • Also, we've seen strange STIC behavior with code running near $C040 that seems to go away when we move the code to a higher address.

 

In your CART.MAC library, the latter range shows as $C022 - $FFFF. Is this wrong?

 

Christmas Carol reserves that range for its "data segment," starting with the title screen's data structures. Is there a problem at addresses $C022 - $C0FF?

I need more time to know inty basic, and especially how to create better graphics, and "sprites"

 

My problem is that I see I have very limited ram resources. I saw above "memory map" say some ram is unused.

can i use this area.

 

Intybasic put its variables around 0x100---->

 

are there other addresses I can use ?

 

In your CART.MAC library, the latter range shows as $C022 - $FFFF. Is this wrong?

 

Christmas Carol reserves that range for its "data segment," starting with the title screen's data structures. Is there a problem at addresses $C022 - $C0FF?

 

Well, yes and no. Theoretically, you should be able to put ROM at $C000 - $C021 and $C023 onward. And with Christmas Carol we never had a problem. In fact, any game that uses color stack mode is probably fine, and I seem to recall Carol uses color stack throughout.

 

See this thread, though, for why I'm suggesting folks put some additional buffer there as a general prophylactic: http://atariage.com/forums/topic/224875-weirdest-intellivision-bug-ive-ever-seen/

 

Basically, there's something weird going on at least with program fetches in that address range, and it can cause your game to mysteriously flip to color stack mode when you're not expecting it. We discovered it during Kroz testing.

 

EDIT: I see you've seen the thread. And no, there's no new information on why this happens.

Edited by intvnut

I need more time to know inty basic, and especially how to create better graphics, and "sprites"

 

My problem is that I see I have very limited ram resources. I saw above "memory map" say some ram is unused.

can i use this area.

 

Intybasic put its variables around 0x100---->

 

are there other addresses I can use ?

 

The Intellivision has 8-bit RAM at $100 - $1EF (sometimes called "scratch RAM"), and 16-bit RAM at $200 - $35F (sometimes called "system RAM"). The display (also known as BACKTAB) lives at $200 - $2EF. There's also 512 bytes of Graphics RAM (GRAM) at $3800 - $39FF that holds pictures for up to 64 different 8x8 tiles. The names "scratch RAM" and "system RAM" come from the limited official documentation that's shown up describing the Intellivision system components. For example, the GI datasheet for the AY-3-9600 that provides the 16-bit RAM calls that memory "System RAM."

 

$100 - $101 is reserved for the interrupt service vector. This is fixed by the EXEC and you cannot change it. Other than that, how the rest gets used in IntyBASIC is defined by IntyBASIC. Perhaps nanochess can comment.

 

In any case there isn't a lot of RAM available by default. If your game truly needs more RAM, some cartridge designs offer additional RAM. My JLP boards offer 8K words of 16-bit RAM from $8040 - $9F7F. I understand GroovyBee's Bee3 boards offer similar.

 

But in any case, unless you're computing new sprite images on the fly, you shouldn't need much RAM for more sprite or other graphics, other than the ability to load pictures into GRAM. None of those really consume scratch RAM or system RAM. The pictures are all loaded from ROM into GRAM.

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...