Jump to content

Photo

Action! Source Code

Action! Source Code

281 replies to this topic

#76 luckybuck OFFLINE  

luckybuck

    Stargunner

  • Topic Starter
  • 1,049 posts

Posted Sun Feb 8, 2015 5:32 PM

So include the Stork version?

 

Great!

 

Then we are complete with the versions... ;-)

 

Stork.jpg

 



#77 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Sun Feb 8, 2015 6:03 PM

Just located one of my most-hated bugs:

;
; .BYTE 0,0,0,0,0,0,0,0 ; 7
strig tax
lda $d010,x
sta args
rts
;

Strig() reads the hardware register instead of the shadow register. This made my game totally uncontrollable because Action! is so fast, the bouncing of the mechanical trigger is visible.

Edited by JAC!, Sun Feb 8, 2015 6:09 PM.

  • Stephen and Mathy like this

#78 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Sun Feb 8, 2015 6:49 PM

Looks like some things were foreseen in the lexer/parser but didn't make it into the language definition. They exist as unused token definitions in the lexer.

- case/esac
- code/edoc
- real
- string
- for ... downto

#79 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Sun Feb 8, 2015 7:50 PM

And finally I manged to get the logic behind the bank id straight. The issue was the release source uses ebank=1 for the editor bank. But actually the value use in the ROM is 3 except on the bank id location itself ($AFFF). The trick behind all that is that OSS type 15 carts only use bits 3 and 0 for bank selection. Hence ebank=3 gives the correct result and the bank id (in fact all of them) must be masked with %1001.
 
bankmsk	equ	%1001			;Only bit 3 and 0 are relevant

	.if cartridge_type = 15		;OSS one chip 16 KB cartridge 
ebank	equ	3			;Editor bank, was 1 in original source
lbank	equ	0			;Library bank
cbank	equ	9			;Compiler bank
	.else
	.error "Unsupported cartridge type ", cartridge_type, ". Use 15 or 43."
	.endif

	.align	el+$0fff,$00	; Fill with empty bytes instead of $ff.
	org	el+$0fff
	.byte	ebank & bankmsk	; Bank identifier at end of bank.
Et voila:
Comparing files ACTION.rom and ACTION-TYPE-15.ROM
FC: no differences encountered

I also managed to add structuring for the majority of labels. That means there are not so many global labels anymore. Instead nested scopes provide context is restrict visibility. In higher level languages you'd call that "public" and "private". Editor, Monitor, Parse (Lexicon) and Compiler are now properly separated in terms of symbols.

Action!-Symbols.png

Interesting for me: This was the first time I really needed the ".LOCAL" feature of MADS. It allows for having the same scope ("name") merged from different parts of the file. Because neither the editor nor the compiler fit into their available 4k bank, part of their code was moved by the original author to the main bank. By using ".local compiler" in both banks, I can address them logically as one again.
 
	icl	"SCREEN.MAC.asm"
	.local	compiler	; Main bank part of the compiler
	icl	"compiler/LEXICON.asm"
	.endl
	icl	"MAIN.MSC.asm"
	icl	"MAIN.BNK.asm"
mainend
	.align	ml+$08d8,$00	; Fill with empty bytes instead of $ff
	org	ml+$08d8
	.local	editor		;Main bank part of the editor
	icl	"editor/EDIT.FND.asm"
	icl	"editor/EDIT.SUB.asm"
	icl	"editor/EDIT.TAB.asm"
	.endl
editend
	.align	ml+$0a80,$00	; Fill with empty bytes instead of $ff.
	org	ml+$0a80
	icl	"AMPL.SEG.asm"

Edited by JAC!, Sun Feb 8, 2015 7:51 PM.

  • Stephen , Bunsen , MrFish and 2 others like this

#80 luckybuck OFFLINE  

luckybuck

    Stargunner

  • Topic Starter
  • 1,049 posts

Posted Sun Feb 8, 2015 7:56 PM

Wow! Sleepless in Germany... ;-)



#81 Gury OFFLINE  

Gury

    Stargunner

  • 1,314 posts

Posted Sun Feb 8, 2015 8:08 PM

Great find, I am pleased! This is Holy Grail of programming on Atari.

 

case/esac... I hope we could implement CASE structure into Action! language in the future.


  • Stephen and Synthpopalooza like this

#82 luckybuck OFFLINE  

luckybuck

    Stargunner

  • Topic Starter
  • 1,049 posts

Posted Sun Feb 8, 2015 8:11 PM

As you said future! This is the beginning of a new Atari age and we all share it. The future is now.

 

Rock and Roll! ;-)

 

let the good times roll!



#83 Synthpopalooza OFFLINE  

Synthpopalooza

    Stargunner

  • 1,472 posts
  • Location:knoxville, TN

Posted Sun Feb 8, 2015 10:02 PM

What about floating point numbers?  Maybe as an option, I know it was left out to keep the action code optimised, but maybe there's a way to write a custom OS routine to do FP numbers?



#84 luckybuck OFFLINE  

luckybuck

    Stargunner

  • Topic Starter
  • 1,049 posts

Posted Mon Feb 9, 2015 3:08 AM

You already checked in here:

 

AtariWiki V3: ACTION

 

? In the Toolkit disk is the solution for REAL, in the Toolkit manual the description.

 

Enjoy.



#85 ricortes OFFLINE  

ricortes

    Dragonstomper

  • 686 posts

Posted Mon Feb 9, 2015 11:48 AM

I think floating point is left difficult to encourage you not to use it. j/k

 

It could be a little easier to use. Using the FP routines from assembler or Action isn't bad to the point of being unusable. I did a couple of programs that used the routines when translating a BASIC program to Action. I think at least one was from one of the Compute Books ~Book Two of Atari Programming, Point Set Graphics.

 

Much of the need for FP would be eliminated easier by having something like a long integer and would probably be easier to implement. 



#86 luckybuck OFFLINE  

luckybuck

    Stargunner

  • Topic Starter
  • 1,049 posts

Posted Mon Feb 9, 2015 12:04 PM

:-)

 

As a scientist I am 100 % with you. This goes even back to a dream a have: Fortran 77/90 for Atari...

 

Well, let's give the people some time for developing.

 

My blueprint is as follows:

 

(Atari Basic Ver. C (source code we already have), TurboBasic XL (source code is in the making), Basic XL (source code we already have), Basic XE (), Altirra Basic (source code we already have), MS Basic I and II(?) to finally build the last Atari Super Basic on an open source base.

 

Then(!) there has to be the FP integrated: here is my plan: OS source listing we already have, plus the Atari Calculator routines:

 

https://atariwiki.or...tari Calculator

 

please go up to the end of the page, plus the fast ones from Charles Marslett. Goal: Poke "precision,2" for 2 digits, up to 15 or 16...

 

Action! is already in the making.

 

Mac/65 or a Super Assembler. Well, that would be hard, MADS we do have, but we will see.

 

We live in interesting times... :-)



#87 ricortes OFFLINE  

ricortes

    Dragonstomper

  • 686 posts

Posted Mon Feb 9, 2015 12:29 PM

Just located one of my most-hated bugs:

;
; .BYTE 0,0,0,0,0,0,0,0 ; 7
strig tax
lda $d010,x
sta args
rts
;

Strig() reads the hardware register instead of the shadow register. This made my game totally uncontrollable because Action! is so fast, the bouncing of the mechanical trigger is visible.injj

 

BTW: Great work!

 

Thanks for pointing this out because it makes it possible to do a work around if it becomes a problem. It probably should be left as is in the official cartridge just in case someone needs it that fast or has already adapted their program to account for it. It's pretty easy to just read the debounced shadow register under program control.



#88 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Wed Feb 11, 2015 4:43 PM

I see it the other way around. All other functions use the shadow registers, only this only bails out with no reason. There's a reason why the shadow registers are there for all input controls: Updates more frequent than the frame rate are useless and can even break your control flow if you're not careful. Well unless you turn use the joystick trigger as digital analyzer, but esp. then you'd never go via a function call with it's overhead to read the hardware. You'd simply define INPUT = $D010, OUTPUT=$D01A and code something like DO:OUTPUT=INPUT<<2:OD .

In fact directly using the hardware registers is one of the most frequent bug in software released for the 8-bit in recent years. You don't have any issue in emulation and the on real hardware the game becomes uncontrollable and annoying and you don't know why.

Edited by JAC!, Wed Feb 11, 2015 4:44 PM.


#89 Kr0tki OFFLINE  

Kr0tki

    Stargunner

  • 1,133 posts
  • Location:Warszawa, Poland

Posted Thu Feb 12, 2015 11:53 AM

I see it the other way around. All other functions use the shadow registers, only this only bails out with no reason.


To me, it looks like a conscious choice, and you forgot, in your game, to enable latching of TRIG inputs with GRACTL bit 2.

Edited by Kr0tki, Thu Feb 12, 2015 11:53 AM.


#90 ricortes OFFLINE  

ricortes

    Dragonstomper

  • 686 posts

Posted Thu Feb 12, 2015 2:44 PM

99% of problems are just solved by documenting the behavior. As KrOtki points out, set GRACTL. As JAC points out, could be fixed in cart which in no way inhibits your ability to directly read the hardware register. I'm not sure about the runtime packages because at least one is a directly copy of the cart routines, all can be patched or edited to do what you actually want. 

 

There's no way of knowing if there was a piece of hardware that actually needs the routine as written. It is probably inconsequential at this stage, something like Mr. Parker used an 800 with a Corvus HD that needed it???

 

For any substantial Action! program, they all end up being a compile from disk. Pretty easy to patch the runtime to make sure it is doing what you intended. i.e.

BYTE FUNC STrig=*(BYTE p)
[$29$03$AA$BD$84$02$85$A0$60]


#91 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Thu Feb 12, 2015 3:02 PM

The name of the function is the name of the shadow register.

Atari Basic (which is the defining base for all these function and their names) uses shadow registers for everything.
The Action! joystick routines published in the OSS Action! toolkit use shadow registers.
The other available 3rd party runtimes all use shadow registers for everything.
Nobody presses a fire button more than 50 times a second.
I personally spent hours trying to find out why a simple 4 line program transferred from Atari Basic didn't work.
That are enough reasons for me personally to consider this a fix.  :) 


Edited by JAC!, Thu Feb 12, 2015 3:08 PM.

  • Kyle22 , flashjazzcat and venom4728a like this

#92 ricortes OFFLINE  

ricortes

    Dragonstomper

  • 686 posts

Posted Thu Feb 12, 2015 6:57 PM

Right with the one possible exception of the runtime that just copies the routines directly from the cart. I can't recall the name of the programmer but I think you can find it in the umich Atari 8 bit archive if you need to know his name for some reason. This would of course means it copied the bug.

 

AFAIK, not many programmers<0?> used that technique/RT as people mostly used the Jeff Reister PD RT or commercial RT package.

 

I may have to revisit some of my odd hacks. I recall/still have the prototype of a single joystick port EPROM programmer I made. I used three 74ls164 to convert bit wise data into a byte and address. Pretty sure I had huge problems with denouncing the circuit. I think I used the 4 bits of port to handle clock, control, and data, and maybe Strig to read it back. Odd because it was digital but the noise introduced by hard switching and RFI blocking components on the J/S was enough to glitch the circuit.



#93 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Mon Feb 16, 2015 5:57 PM

Spent the whole day adding yet more structure. The source is now organized in 39 separate files in 6 separate folders (compiler, editor, ampl, lib, main, root). 796 of of the 981 labels now have qualifiers, i.e. the are no longer plain global labels like "putch1" but "screen.putch.putch1". This gives locality to the labels and help to relate the label with the module or source file it is coming from. The remaining global labels are mainly system equates, which is OK. The source still compiles 100% to the original cartridge, which is still important at the current state to ensure I didn't break something already.
 
Commits.png
 
I also added the output of the "free" space available on the cartridge:
 
Aligning $B8D4 - $B8D8($0005 bytes free)
Aligning $BA7D - $BA80($0004 bytes free)
Aligning $BFF1 - $BFFA($000A bytes free)
Ending switched bank LL/LBANK: $AFFE - $AFFF($0002 bytes free)
Ending switched bank CL/CBANK: $AFFD - $AFFF($0003 bytes free)
Ending switched bank EL/EBANK: $AFFD - $AFFF($0003 bytes free)
 
So a total of 27 bytes, but as you can see in each bank, well... It must have been a hell of a job scramming it all in there. No wonder some commands had to be left out. There's heavy reuse across all modules and banks. This reuse actually breaks the program structure, but it saved some precious bytes. That's also why the main bank contains arbitrary code fragments from all other banks. Obviously the code was shifted "here and there" manually to find a best fit.
 
But the total killer code is the hash table which is used to map key words and procedure names to their definition in the ROM. The low-bytes of the hash values are used as index in a lookup table. And where there were gaps in the hash values, some small code fragments were squeezed in.
 
.byte <??en56
.byte <en3
.byte 0,0 ; 2
;
; .BYTE 0,0,0,0,0,0,0,0,0,0
; .BYTE 0,0,0,0,0,0,0,0,0 ; 17
??en6 .byte 6,'PrintF',200
.word libio.prtf ; #117
.byte 6,17,12,12,12,12,12
;
.byte <??en61
.byte <??en35
.byte 0 ; 1
.byte <??en39
There's even a hidden 3rd copyright notice encoded:
;
; .BYTE 0,0,0,0,0,0,0,0,0,0 ; 10
; (c)1983ACS in internal char. qcode
;copyright
	.byte	8,99,9,17,25,24,19,33,35,51
If this table is every moved one byte in either direction, it will probably go to hell with no way of knowing whether another valid sequence exists at all.

Edited by JAC!, Mon Feb 16, 2015 5:58 PM.

  • Stephen , MrFish , flashjazzcat and 1 other like this

#94 flashjazzcat ONLINE  

flashjazzcat

    Quadrunner

  • 14,587 posts
  • Location:United Kingdom

Posted Mon Feb 16, 2015 6:40 PM

Good stuff. I once did the same thing with a bit shifting LUT whose entries were 16 bytes apart in The Last Word when I was running out of space: crammed other variables and data between them.

#95 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Mon Feb 16, 2015 6:42 PM

Couldn't resist. Here's a first plain 16k ROM (not OSS). At least it starts in Altirra, no compiling tested yet at all.

Attached Files


Edited by JAC!, Mon Feb 16, 2015 6:47 PM.

  • flashjazzcat and KlasO like this

#96 gozar OFFLINE  

gozar

    Dragonstomper

  • 991 posts
  • Location:Ohio

Posted Mon Feb 16, 2015 7:00 PM

Hmmm, crashes atari800 3.0.0 when you try to compile.

PROC MAIN()
 PRINTE("HELLO WORLD")
RETURN

Not that you should lose any sleep over it, you're doing amazing work!



#97 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Mon Feb 16, 2015 7:58 PM

Well, if there is ONE thing, a compiler is supposed to do, then it's compiling HELLO WORLD correctly :-).
New build with 16k ROM and a first XEX version. I think the screen is not cleared correctly when leaving the editor, but the HELLO world is compiled & printed now.

Attached Files


Edited by JAC!, Mon Feb 16, 2015 7:58 PM.

  • Stephen , pirx and MrMartian like this

#98 pirx OFFLINE  

pirx

    Moonsweeper

  • 456 posts
  • Location:Poland

Posted Tue Feb 17, 2015 4:04 AM

Just an idea - maybe it would be possible to despaghetti the code so it takes more banks (e.g. 32 or 64KiB), but is devoid of these messy byte saving techiniques



#99 JAC! OFFLINE  

JAC!

    Stargunner

  • 1,845 posts
  • Always looking for GFX and MSX for my demos
  • Location:Lebach, Germany

Posted Tue Feb 17, 2015 6:08 AM

Ultimately, that's the plan. But for now it's very important to be able to back-track all my syntactic changes to make sure it is 100% compatible to the original. The result are of course lot of conditional assembly blocks that make the source more complicated overall.
 
;	RstBank()
;	---------
rstbank	.proc
	.if	.def bank
	php	
	pha	
	tya	
	ldy	curbank
rbank1	sta	bank,y
	tay	
	pla	
	plp
	.endif
init	rts	
But they allow me to gradually remove the parts will not be required anymore in future. OSS bank switching and ROM protection belong to this.
 
;SPLInit .proc ; init compiler RAM	;TODO This should be a subroutine

	.if	.def ramzap
	.if	ramzap
	jsr	editmain.fmcmd.zap4
	.else	
	nop	
	nop	
	nop	
	.endif
	.endif
My plan is to have a slightly modified OSS compatible version that can replace the original. Given the 27 free bytes, that will include only simple things like case-insensitive search (which I once did as patch), less anyoing "BEEEEEEEEEEEEEEEEEEEEEEP" and the mentioned runtime lib fixes.
I'll freeze that version as 3.7 then in the original memory layout.

Everything beyond that will result XEX and ROM version depending on the demand. Maybe I'll start a poll then to ask. I think a XEX version with support to put itself under the OS or into extended RAM (so it doesn't get lost when the program crashes) will be the best options. Also I don't have to fiddle around with ROM size limits then.

For this version I will no longer stick to the original memory layout and will also untangle the source. In fact the XEX and CAR in my previous post already uses a better memory layout and have all banking and ROM protection stuff removed:; $D6 bytes free in the 16 ROM now.
  • Stephen , pirx and flashjazzcat like this

#100 danwinslow OFFLINE  

danwinslow

    River Patroller

  • 2,591 posts

Posted Tue Feb 17, 2015 7:11 AM

JAC, you are doing amazing work. This is going to be a really valuable resource for Atari programming in general.


  • flashjazzcat likes this




1 user(s) are browsing this forum

0 members, 1 guests, 0 anonymous users