Jump to content

Search the Community

Showing results for tags 'pascal'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Atari Systems
    • Atari General
    • Atari 2600
    • Atari 5200
    • Atari 7800
    • Atari Lynx
    • Atari Jaguar
    • Atari VCS
    • Dedicated Systems
    • Atari 8-Bit Computers
    • Atari ST/TT/Falcon Computers
    • Atari Portfolio
  • Classic Consoles
    • Classic Console Discussion
    • ColecoVision / Adam
    • Intellivision / Aquarius
    • Bally Arcade/Astrocade
    • Odyssey 2 / Videopac
    • Vectrex
    • Nintendo Entertainment System (NES) / Famicom
    • Super Nintendo Entertainment System (SNES) / Super Famicom
    • Sega Genesis
    • 3DO Interactive Multiplayer
    • Dreamcast
    • SMS High Score Club
    • TG-16/PC Engine High Score Club
  • Classic Computing
    • Classic Computing Discussion
    • Apple II Computers
    • TI-99/4A Computers
    • Commodore 8-bit Computers
    • Commodore Amiga
    • Tandy Computers
  • Modern Consoles
    • Modern Gaming Discussion
    • Sony Playstation 5
    • Xbox Series S/X
    • Atari VCS (Redirect)
    • Nintendo Switch
    • Microsoft Xbox One
    • Sony PlayStation 4
    • Microsoft Xbox 360
    • Sony Playstation 3
    • Nintendo Wii / Wii U
  • Gaming General
    • Gaming General Discussion
    • Arcade and Pinball
    • Emulation
    • Hardware
    • Prototypes
    • Gaming Publications and Websites
    • International
  • Marketplace
    • Buy, Sell, and Trade
    • Auction Central
    • Wanted
    • Free Games and More
    • User Feedback Forum
  • Community
  • Community
    • Events
    • Show Us Your Collection!
    • Member Blogs
    • High Score Clubs
    • Poll Forum
    • Contests
    • User Groups
    • AtariAge News Discussion
    • User Submitted News
  • Game Programming
    • Homebrew Discussion
    • Programming
    • Hacks
  • Site
    • Announcements
    • Forum Questions and Answers
    • AtariAge Store Discussion
    • Site and Forum Feedback
    • Rarity Guide
    • Archived Forums
  • PC Gaming
  • The Club of Clubs's Discussion
  • I Hate Sauron's Topics
  • 1088 XEL/XLD Owners and Builders's Topics
  • Atari BBS Gurus's Community Chat
  • Atari BBS Gurus's BBS Callers
  • Atari BBS Gurus's BBS SysOps
  • Atari BBS Gurus's Resources
  • Atari Lynx Programmer Club's CC65
  • Atari Lynx Programmer Club's ASM
  • Atari Lynx Programmer Club's Lynx Programming
  • Atari Lynx Programmer Club's Music/Sound
  • Atari Lynx Programmer Club's Graphics
  • The Official AtariAge Shitpost Club's Shitty meme repository
  • The Official AtariAge Shitpost Club's Read this before you enter too deep
  • Arcade Gaming's Discussion
  • Tesla's Vehicles
  • Tesla's Solar
  • Tesla's PowerWall
  • Tesla's General
  • Harmony/Melody's General
  • Harmony/Melody's CDFJ
  • Harmony/Melody's DPC+
  • Harmony/Melody's BUS
  • Harmony/Melody's CDFJ+
  • ZeroPage Homebrew's Discussion
  • Furry Club's Chat/RP
  • PSPMinis.com's General PSP Minis Discussion and Questions
  • PSPMinis.com's Reviews
  • Atari Lynx 30th Birthday's 30th Birthday Programming Competition Games
  • 3D Printing Club's Chat
  • Drivers' Club's Members' Vehicles
  • Drivers' Club's Drives & Events
  • Drivers' Club's Wrenching
  • Drivers' Club's Found in the Wild
  • Drivers' Club's General Discussion
  • Dirtarians's Members' Rigs
  • Dirtarians's Trail Runs & Reports
  • Dirtarians's Wrenching
  • Dirtarians's General Discussion
  • The Green Herb's Discussions
  • Robin Gravel's new blog's My blog
  • Robin Gravel's new blog's Games released
  • Robin Gravel's new blog's The Flintstones Comic Strip
  • Atari Video Club's Harmony Games
  • Atari Video Club's The Atari Gamer
  • Atari Video Club's Video Game Summit
  • Atari Video Club's Discsuuions
  • Atari Video Club's Concerto Games
  • Atari Video Club's AVC Games
  • Star Wars - The Original Trilogy's Star Wars Talk
  • PlusCart User's Bug reports
  • PlusCart User's Discussion
  • DMGD Club's Incoming!
  • DASM's General
  • AtariVox's Topics
  • Gran Turismo's Gran Turismo
  • Gran Turismo's Misc.
  • Gran Turismo's Announcements
  • The Food Club's Food
  • The Food Club's Drinks
  • The Food Club's Read me first!
  • The (Not So) Official Arcade Archives Club's Rules (READ FIRST)
  • The (Not So) Official Arcade Archives Club's Feedback
  • The (Not So) Official Arcade Archives Club's Rumor Mill
  • The (Not So) Official Arcade Archives Club's Coming Soon
  • The (Not So) Official Arcade Archives Club's General Talk
  • The (Not So) Official Arcade Archives Club's High Score Arena
  • Adelaide South Australia Atari Chat's General Chat & Welcome
  • Adelaide South Australia Atari Chat's Meets
  • Adelaide South Australia Atari Chat's Trades & Swaps
  • KC-ACE Reboot's KC-ACE Reboot Forum
  • The Official Lost Gaming Club's Lost Gaming
  • The Official Lost Gaming Club's Undumped Games
  • The Official Lost Gaming Club's Tip Of My Tounge
  • The Official Lost Gaming Club's Lost Gaming Vault
  • The Official Lost Gaming Club's Club Info
  • GIMP Users's Discussion
  • The Homebrew Discussion's Topics
  • Hair Club for Men's Bald? BEGONE!
  • Alternate Reality's Topics
  • Board games, card and figure games's Topics
  • please delete's Topics
  • StellaRT's Topics
  • DOS and Vintage PCs's DOS Discussion

Blogs

  • BinaryGoddess' Blog
  • Albert's Blog
  • MegaManFan's Blog
  • Ed Siegler's Blog
  • FireTiger's Blog
  • Atari Rescue Group's Blog
  • EricBall's Tech Projects
  • liquid_sky's Blog
  • Cybernoid's Blog
  • Lost Blog
  • shep's Blog
  • Trey's Blog
  • Boo
  • Kepone's Blog
  • Beware of Kiwi
  • Fun in the beer mines
  • PacManPlus' Blog
  • Atari 8-bit Moria port
  • Tim's Blog
  • Mindfield's Chewy-Centered Blog
  • The Long Dark Teatime of the Soul
  • TP's Blog
  • Adam Sessler's Brutally Honest Blog
  • Shut Up and Play Yer Atari
  • None
  • Atarinvader's Blog
  • Atari 8-bit archiving
  • Brunobits' Blog
  • ATARIeric's Blog
  • wrenchien's Blog
  • Trade-N-Games' Blog
  • wapchimp's Blog
  • Shared Words
  • Bastard's Blog
  • homerwannabee's Blog
  • Haydn Jones' Blog
  • The World According To Yuppicide
  • How I did It
  • Buck's Blog
  • atwwong's Blog
  • 1
  • sandmountainslim's Blog
  • Atari Jaguar Projects + More
  • StanJr's Blog
  • Schmutzpuppe's Blog
  • Bullitt's Blog
  • panda_racer's Blog
  • Inky's Blog
  • Lauren's Place
  • DanBoris' Tech Blog
  • atariauctions' Blog
  • Planet Bob
  • CSIXTY4.com
  • Robin Gravel's Blog
  • lestergame
  • Duke 4ever's Blog
  • Atari Haiku Blog
  • An7ron
  • glitch's Blog
  • Coleco-Atari Era
  • Kenfused's Blog
  • Ralph3's Blog
  • nester's one star gaming
  • Halt and Catch Fire
  • lizard's Blog
  • Laner's Classic Gaming Blog
  • Page 6
  • keilbaca's rants
  • SirWilliam's Blog
  • Birdie3's blog
  • MattG/Snyper2099's Blog
  • madmjennifer's Blog
  • Ablogalypse Now
  • Endless Quest
  • Greenious' Blog
  • wookie's Blog
  • Justclaws' Blog
  • VTAtari's Blog
  • SID CROWE TESTING THE blog softwareeee
  • Dutchman2000's Blog
  • Famicoman's Blog
  • scogey's Blog
  • Retro Gaming Obscuria
  • atarifan49's Blog
  • Chronogamer
  • flavoredthunder's Blog
  • Shernand's Blog
  • Robert M's Blog
  • albaki's Blog
  • BTHOTU's Blog
  • Zach's Projects
  • BuzzTron-451's Blog
  • The Occasional Coder
  • Joystick Lunatic Software on AtariAge
  • Zander's Blog
  • The randomness that is Mr. 8-bit/16-bit.
  • bluetriforce's Blog
  • ubikuberalles' Blog
  • Worm Development Blog
  • Eight Bit's Blog
  • mos6507's Blog
  • phaxda's Blog
  • potatohead's Blog
  • Mountain King's Blog
  • The Southsider
  • The World is Flat?
  • brianwolters' Blog
  • Bidouille's Blog
  • Zybex/Atariware Blog
  • JagDiesel's Palace 2
  • Sega_master's Blog
  • Deep into the Mind Game
  • Bob's Blog
  • Rockin' Kat's Blog
  • Push Me, Pullman
  • (Insert stupid Blog name here)
  • dgob123's INTV Blog
  • Random Terrain's Tetraternarium
  • Odyssey Development Corner
  • Pacmaniax
  • GPD Comics Blog
  • sergiomario's Blog
  • prorobb's Blog
  • Days Atari Events
  • gamester1's Blog
  • Shannon's Blog
  • Mord's Blog
  • liquidcross.com - blog
  • MIPS HEAVY INDUSTRIES
  • MayDay Today
  • javiero's Blog
  • Great Exploitations
  • Monster Angriff's Blog
  • Draikar's Blog
  • Random Acts of Randomness
  • TROGBlog
  • hex65000's Blog
  • Being Of The Importance Of Shallow Musing.
  • daclmi's Blog
  • 2600 in 2006
  • Sayton's Blog
  • For whom it may concern
  • Osbo's Blog
  • ataridude81's Blog
  • Wiesbaden Gaming Lab
  • SpiceWare's Blog
  • The Upward Spiral
  • Web-Frickin'-Log
  • Starosti 8bitového grafika
  • WWW.BUYATARI.TK
  • commodore & atari :)'s Blog
  • Dusk2600's Blog
  • GAMEBOT
  • Lynx 20 years
  • Songbird Productions
  • SpaceInvader's Blog
  • Retro point of view
  • VampyricDreams666's Blog
  • le geek's nonsense
  • Hardcore's Nostalgia
  • 4old-times-sake's Blog
  • shadow460's Blog
  • AtariJr's Blog
  • Memoirs of an X register
  • maximebeauvais' Blog
  • atari2600land's Blog
  • .:maus:.
  • PAM1234's Blog
  • Nabuko's Den
  • Paranoid's Blog
  • Culmins Development's Blog
  • Atari Joe's Flippin' Sweet Blog
  • When Robots Attack
  • Flack's Daily Smack
  • Jboypacman's Blog
  • neonesmaster's Blog
  • Classic Stories
  • Bruce Tomlin's Blog
  • Beetle's Blog
  • 5-11under's Blog
  • EricDeLee's Blog
  • TunnelRunner's Blog
  • jaymz887's Blog
  • fojy-harakiri's Blog
  • Shroo-man's Blog
  • Ataria51's Blog
  • Mr. Pac-Man's Blog
  • JellE's Dwelling
  • Gaming With Rogmeister
  • Pengwin's Blog
  • neotokeo2001's Blog
  • Arcade's Blog
  • R. Jones' Blog
  • payman84ce's Blog
  • Awed Thoughts
  • super mario 64 level editor
  • Christos' Blog
  • atari_collector's Blog
  • imtron's Blog
  • My Vintage Game collection
  • classicgamingguy's Blog
  • HP Atari King of Michigan's Blog
  • Unknown arcade titles from Fighter17
  • Ain't got time for no Jibbajaba
  • Wickeycolumbus' Blog
  • Ramblings of a moron
  • HatNJ's Blog
  • BlogO
  • ELEKTROTECK
  • bf2k+'s Blog
  • ParaJVE's Blog
  • Cody Rushton's blog
  • It's my life!
  • Bakasama's Blog
  • Dennis V's Blog
  • RaRoss' Blog
  • Collecting Demos
  • Dave Neuman's Blog
  • Borntorun's Blog
  • warren798's Blog
  • Tweety's Blog
  • -^CB^-'s Game Reviews
  • seekingarobiejr's Blog
  • revival studios
  • bust3dstr8's Blog
  • Rom Hunter's Blog
  • Shark05's Blog
  • Lord Helmet's Blog
  • ryanez1's Blog
  • kit's Blog
  • Burma Rocks
  • Bubsy Bobcat Fan Blog
  • Habaki's Blog
  • Dan's Road to 2600 nirvana
  • wccw mark's Blog
  • Hornpipe2's Blog
  • Phantom's Blog
  • Piggles' Blog
  • Dino Dash Derby
  • games_player's Blog
  • 1982VideoGames' Blog
  • Cabbage Patch Kids! Lookin' Great!
  • Confessions of an Aging Gamer...
  • theking21083's Blog
  • retrogeek's Blog
  • Liveinabin's scribbles
  • Cimerians' Blog
  • CollectorVision Blog
  • Ransom's Random Posts
  • www.toyratt.com's Blog
  • RonPrice's Blog
  • s0c7's Blog
  • doyman's Blog
  • DJTekid's Blog
  • EG's code blog
  • kiwilove's Blog
  • 8 Bit Addiction
  • Playing With History
  • simonh's Blog
  • Zereox's Blog
  • Draconland
  • chris_lynx1989's Blog
  • Phuzzed's Blog
  • 7800 NZ's Blog
  • Gamera's Reviews: E.T Coming Soon!
  • Iwan´s Irrational!
  • seemo's Blog
  • The Eviscerator Series
  • Noelio's Blog
  • 480peeka's Blog
  • For Next
  • Take 'Em To The Woodshed
  • bankockor Blog
  • Kelp Entertainment
  • 2600 Fun Blogs
  • PinBlog
  • IHATETHEBEARS' BLOG
  • Atari Fan made Documentary
  • Flashjazzcat's Blog
  • THE 1 2 P's Demo/Import/Gaming Blog
  • STGuy1040's Blog
  • enyalives' Blog
  • Mirage1972's Blog
  • blogs_blog_286
  • The Word Of Ogma
  • GC's blog
  • nanobug's monument of geekiness
  • dogcorn's Blog
  • I Can't Think of a Catchy Title
  • please help and share story
  • ivop's Blog
  • what is the chicago basment
  • Cheat Blog
  • zeropolis79's Blog
  • My video game library
  • the.golden.ax's "Oh my Blog"
  • ValuGamer
  • wolfpackmommy's Blog
  • Z80GUY's Blog
  • jwierer's Blog
  • kroogur's Korner
  • Verbal Compost
  • Frizo's Collecting Adventure!
  • Old School Gamer Review
  • ...
  • Rybags' Blog
  • BDW's Blog
  • tweetmemory's Blog
  • toptenmaterial's Blog
  • grafix's Bit Mouse Playhouse
  • S1500's Blog
  • hackerb9's blog
  • EricBall's Tech Projects (PRIVATE)
  • MagitekAngel's Blog
  • I created this second blog on accident and now I can't figure out how to delete it.
  • keilbaca's Blog
  • TestBot4's Blog
  • Old School Gamer Review
  • The Mario Blog
  • GideonsDad's Blog
  • GideonsDad's Blog
  • GideonsDad's Blog
  • Horst's Blog
  • JIMPACK's Blog
  • Blogpocalypse
  • simonl's Blog
  • creeping insanity
  • Sonic R's Blog
  • CebusCapucinis' Blog
  • Syntax Terror Games
  • NCN's Blog
  • A Wandering Shadow's Travels
  • Arjak's Blog
  • 2600Lives' Blog
  • 2600Lives' Blog
  • Kiwi's Blog
  • Stephen's A8 Blog
  • Zero One
  • Troglodyte's Blog
  • Austin's Blog
  • Robert Hurst
  • This Is Reality Control
  • Animan's Blog Of Unusual Objectionalities
  • Devbinks' Blog
  • a1t3r3g0's Blog
  • The 7800 blog
  • 4Ks' Blog
  • carmel_andrews' Blog
  • iratanam's Blog
  • junkmail's RDE&P Blog
  • Lynxman's FlashCard Blog
  • JagMX's Blog
  • The Wreckening
  • roberto's Blog
  • Incagold's Blog
  • lost blog
  • kurtzzzz's Blog
  • Guitarman's Blog
  • Robert @ AtariAge
  • otaku's Blog
  • otaku's Blog
  • revolutionika's Blog
  • thund3r's Blog
  • edweird13's Blog
  • edweird13's Blog
  • That's what she said.
  • Hitachi's Blog
  • The (hopefully) weekly rant
  • Goochman's Marketplace Blog
  • Marc Oberhäuser's Blog
  • Masquane's AtariAge Blog
  • satan165's Dusty Video Game Museum
  • lazyhoboguy's Blog
  • Retail hell (The EB years)
  • Vectrexer's Blog
  • Game Maker to Game Dev
  • Retro Gaming Corporation
  • Hulsie's Blog
  • Tr3vor's Blog
  • Dryfter's Blog
  • Why Are You Even Reading This?
  • Xuel's Blog
  • GamingMagz
  • travelvietnam's Blog
  • pacmanplayer's Blog
  • TheLunarFox's Blog
  • caver's Blog
  • Atari 2600 for sale with 7 games 2 controllers
  • A Ramblin' Man
  • toiletunes' Blog
  • Justin Payne's Blog
  • ebot
  • Markvergeer's Blog
  • GEOMETRY WARS ATARI 2600
  • LEW2600's Blog
  • Pac-Man Vs Puck-Man's Blog
  • Bri's House
  • Les Frères Baudrand's Blog
  • Secure Your E-Commerce Business With ClickSSL.com
  • raskar42
  • The P3 Studio
  • Bydo's Blog
  • defender666's Blog
  • TheSSLstore - SSL certificates Validity
  • Chuplayer's Blog
  • pacman100000's Blog
  • POKEY experiments
  • JPjuice23's Blog
  • Gary Mc's Blog
  • arkade kid's Blog
  • MaXStaR's Blog
  • SUB HUNTER in A8
  • ScumSoft's Blog
  • The Social Gamer
  • Ping. Pong. Ping. Pong.
  • kgenthe's Blog
  • mapleleaves' Blog
  • Dallas' Blog
  • bfg.gamepassion's Blog
  • Esplonky's Blog
  • Fashion Jewellery's Blog
  • Gabriel's Blog
  • CJ's Ramblings
  • Dastari Creel's Blog
  • dobidy's Blog
  • dragging through the retro streets at dawn
  • Please Delete - Created by Accident
  • Nerdbloggers
  • Algus' Blog
  • Jadedrakerider
  • Appliciousblog.com
  • frederick's Blog
  • longleg's Blog
  • Brain droppings...
  • Sandra's blog
  • Bastelbutze
  • polo
  • VectorGamer's Blog
  • Maybe its a Terrible Tragedy
  • Guru Meditation
  • - - - - - -
  • The 12 Turn Program: Board Game Addiction and You
  • Tezz's projects blog
  • chonglily's Blog
  • masseo1's Blog
  • DCUltrapro's Blog
  • Disjaukifa's Blog
  • Vic George 2K3's Blog
  • Whoopdeedoo
  • ge.twik's Blog
  • DJT's High Score Blog [Test]
  • Disjaukifa's Assembly Blog
  • GonzoGamer's Blog
  • MartinP's Blog
  • marshaz's Blog
  • Pandora Jewelry's Blog
  • Blues76's Blog
  • Adam24's AtariAge Blog!
  • w1k's Blog
  • 8-bit-dreams' Blog
  • Computer Help
  • Chris++'s Blog
  • an atari story
  • JDRose
  • raz0red's Blog
  • The Forth Files
  • The Forth Files
  • A.L.L.'s Blog
  • Frankodragon's Blog Stuffs
  • Partyhaus
  • kankan313rd's Blog
  • n8littlefield's Blog
  • joshuawins99's Blog
  • ¡Viva Atari!
  • FujiSkunk's Blog
  • The hunt for the PAL Heavy Sixer
  • Liduario's Blog
  • kakpu's Blog
  • HSC Experience
  • people to fix atari Blog
  • Gronka's Blog
  • Joey Z's Atari Projects
  • cncfreak's Blog
  • Ariana585's Blog
  • 8BitBites.com
  • BrutallyHonestGamer's Blog
  • falcon_'s Blog
  • lushgirl_80's Blog
  • Lynx Links
  • bomberpunk's Blog
  • CorBlog
  • My Ideas/Rants
  • quetch's Blog
  • jamvans game hunting blog
  • CannibalCat's Blog
  • jakeLearns' Blog
  • DSC927's Blog
  • jetset's Blog
  • wibblebibble's Basic Blog
  • retrovideogamecollector's Blog
  • Sonny Rae's Blog
  • The Golden Age Arcade Historian
  • dianefox's Blog
  • DOMnation's Blog
  • segagamer99's Blog
  • RickR's Blog
  • craftsmanMIKE's Blog
  • gorf68's Blog
  • Gnuberubs Sojourn Dev Journal
  • B
  • iesposta's Blog
  • Cool 'n' Crispy: The Blog of Iceberg_Lettuce
  • ahuffman's Blog
  • Bergum's Thoughts Blog
  • marminer's Blog
  • BubsyFan101 n CO's Pile Of Game Picks
  • I like to rant.
  • Cleaning up my 2600
  • AnimaInCorpore's Blog
  • Space Centurion's Blog
  • Coleco Pacman Simulator (CPMS)
  • ianoid's Blog
  • HLO projects
  • Retro Junky Garage
  • Sega Genesis/Mega Drive High Score Club
  • Prixel Derp
  • HuckleCat's Blog
  • AtariVCS101's Blog
  • Tales from the Game Room's Blog
  • VVHQ
  • Antichambre's Blog
  • REMOVED BY LAW AUTHORITY
  • Synthpop Universe
  • Atari 5200 Joystick Controllers
  • Top 10 Atari 2600 Games
  • Is Atari Still Cool?
  • Buying Atari on Ebay
  • matosimi's Blog
  • GadgetUK's Blog
  • The StarrLab
  • Scooter83 aka Atari 8 Bit Game Hunters' Blog
  • Buddpaul's Blog
  • TheGameCollector's Blog
  • Gamming
  • Centurion's Blog
  • GunsRs7's Blog
  • DPYushira's Entertainment Blog
  • JHL's Blog
  • Intellivision Pierce's Blog
  • Manoau2002 Game and Vinyl Blog
  • Diamond in the Rough
  • Linky's Blog
  • flashno1's Blog
  • Atari 2600 Lab
  • jennyjames' Blog
  • scrottie's Blog
  • Draven1087's Blog
  • Omegamatrix's Blog
  • MegaData Manifesto
  • Selling Atari on Ebay.
  • Unfinished Bitness
  • TI-99/4A Stuff
  • eshu's blog
  • LaXDragon's Blog
  • GozAtari8
  • Bio's Blog of Randomness
  • Out of the Pack
  • Paul Lay's Blog
  • Make Atari 2600 games w/o programming!
  • Rudy's Blog
  • kenjennings' Blog
  • The Game Pit
  • PShunny's Blog
  • Ezeray's Blog
  • Atari 2600 game maps
  • Crazy Climber Metal
  • Keith Makes Games
  • A virtual waste of virtual space
  • TheHoboInYourRoom's Blog
  • Msp Cheats Tips And Techniques To Create You A Better Gamer
  • Tursi's Blog
  • F#READY's Blog
  • bow830
  • Gernots A500 game reviews
  • Byte's Blog
  • The Atari Strikes Back
  • no code, only games now
  • wongojack's Blog
  • Lost Dragon's Blog
  • Musings of the White Lion
  • The Usotsuki Crunch
  • Gunstar's Blogs
  • Lesles12's Blog
  • Atari Randomness
  • OLD CS1's Blog
  • waterMELONE's Blog
  • Flickertail's Blog
  • Dexter's Laboratory Blog
  • ATASCI's Blog
  • ATASCI's Blog
  • --- Ω ---'s Blog
  • mourifay's Blog
  • Zsuttle's gaming adventures
  • Doctor Clu's Space Shows
  • TWO PRINTERS ONE ADAM
  • Atari Jaguar Game Mascots
  • Learning fbForth 2.0
  • splendidnut's Blog
  • The Atari Jaguar Game by Game Podcast
  • Syzygy's Story Blog
  • Atarian Video Game Reviews
  • Caféman's Blog
  • IainGrimm's Blog
  • player1"NOT"ready's Blog
  • Alexandru George's Blog
  • BraggProductions' Blog
  • XDK.development present Microsoft Xbox One Development
  • Song I Wake Up To
  • Jeffrey.Shamblin's Blog
  • Important people who shaped the TI 99/4A World
  • My blog of stuff and things
  • David Vella's Blog
  • Osgeld's Blog
  • CyranoJ's ST Ports
  • InnovaX5's Blog
  • Star_Wars_Collector
  • Alp's Art Blog
  • Excali-blog
  • STGraves' Blog
  • Retro VGS Coleco Chameleon Timeline
  • Geoff Retro Gamer
  • Geoff1980's Blog
  • Coleco Mini
  • Coleco Mini
  • 7399MGM's Blog
  • 7399MGM's Blog
  • doubledragon77's Blog
  • Ballblogɀer
  • pitfallharry95's Blog
  • BawesomeBurf's Blog
  • Fultonbot's Atari Blog
  • Dmitry's Blog
  • Kaug Neatos Crash Bandicoot Bandwagon
  • lexmar482's Blog
  • vegathechosen's Blog
  • Atari 2600JS
  • Doctor Clu's Dissertations
  • schmitzi's Blog
  • BNE Jeff's Blog
  • AverageSoftware's Development Blog
  • FireBlaze's Blog
  • Atarimuseum.nl
  • Vorticon's Blog
  • TurkVanGogH GameZ's Blog
  • bow830's Blog
  • Arcade Attack - Retro Gaming Blog
  • MrRetroGamer's Blog
  • GG's Game Dev, Homebrew Review, Etc. Log
  • dazza's arcade machine games
  • Alcor450's Blog
  • The Outback
  • -^CroSBow^-'s Hardware Videos
  • Captain's Blog
  • Memoirs of a Novelty Account
  • newcoleco's Random Blog
  • Second-Hand Shop
  • Doctor Clu's BBS Trotter
  • Lunar eclipse of the mind
  • simon2014's Blog
  • PhilipTheWhovian's Blog
  • Troff the Shelf
  • jacobus Indev
  • Pac & Pal for the Atari 2600 fan project
  • drawscreen then reset
  • Retrogaming Ramblings
  • G-type's Blog
  • Blog o' Buttons
  • DarQ Massacres' Atari 2600 collection
  • FireStarW's Blog
  • Bobbety_F's Blog
  • Rose-Tinted Recollections
  • Young Guy Experiencing Atari
  • Gray Defender's Blog
  • atasciiview
  • 2600 games worse then E.t
  • ZippyRedPlumber's Blog
  • game_escape's Blog
  • Jackel192's Blog
  • The UAV Blog
  • MykGerard
  • OS9Dude's Blog
  • FPGA video game console
  • darryl1970's Blog
  • Funkmaster V's Gettin' Hip with tha Atari 7800
  • AtariMI1978's Blog
  • AtariMI1978's Blog
  • vidak's Blog
  • 8-bit Computer System Colors in Food Coloring
  • WebSiteRing
  • The Best Assembly Computer
  • As time goes by ...
  • Atari 2600 Collection Bulk Box/ Cartridge Sale
  • T.R.A.S.H Blog
  • goodlasers' Blog
  • GauntletKing2878's Blog
  • My Inner Geek
  • A Raccoon's Retrocade Romp - AA Edition
  • homeboy's Blog
  • ThatAtomCat's Blog
  • Hawk's Blog
  • Bryan's Random Stuff
  • Developing Atari Programs on the Atari 800
  • Eltigro's Blog
  • Memories Limited to 640KB
  • my journey to completing the entire Atari libaray
  • Roblox
  • Question for Homebrew publishers
  • zilog_z80a's Blog
  • Return of the Bobcat
  • deepthaw's Blog
  • Little bit of this and little bit of that
  • Shannon's Blog
  • DoctorSpuds Reviews Things
  • Atari Portfolio Page On Facebook
  • azure's Blog
  • The Atari Kid
  • Alien Isolation Blog
  • Atari_Ace's Blog
  • AtariAdventure's Blog
  • AtariCrypt
  • acsabo's Blog
  • Bioshock Text adventure
  • AtariAdventure Reviews
  • Infinite Warfare Specialist
  • Karl's Blog
  • Bjorkinator's Babbles
  • DZ-Jay's Random Blog
  • CX40Hero's Blog
  • Heroes & Shadows Dev Blog
  • Empty
  • GoldLeader's Blog
  • Adventures in CC65
  • CS2X C# on Atari
  • pboland's Blog
  • Matts's Blog
  • orrko8791's Blog
  • orrko8791's Blog
  • Revontuli's Blog
  • Not Steve's Blog
  • Not Steve's Blog
  • SPACE ROANOKE
  • My life
  • skycop's Blog
  • cessnaace's Blog
  • Omegasupreme's Blog
  • Atari 2600 A/V Mods Wiki
  • Mike Harris' Blog
  • Skwrl63's Blog
  • sometimes99er
  • Mallard Games Development Blog
  • Regaining an Obsession
  • Psi-5
  • The Atari Journals
  • Herovania
  • TBA
  • Bluejay Records Co.
  • Running On Fumes
  • Mozartkügel's Midnight Retro Development
  • Alcadon
  • baktra
  • Flojomojo's Simple Mind
  • MarkO
  • Lazydead's Loose Ends
  • OldSchoolRetroGamer's Bloggy Nonsense
  • Magmavision After Dark
  • My Homebrew Devlog
  • BUBSY Blogs [blank]
  • Too young for Atari, too old for XBox
  • KC-ACE Blog
  • Brown Altitude Bar
  • Bubsy TV Pilot Wiki
  • Poltergeist
  • Projektstunde
  • bluejay's corner of random shit
  • SpornyKun
  • alex_79's Blog
  • Atari Label Reproduction/ Relabeling
  • Ephemeral
  • My opinion and story about Atari 2600
  • Sony PlayStation 5/PS5™ Development Kit (Dev Kit) for SALE
  • Delete
  • Superkitten
  • Doublediwn
  • Reindeer Flotilla
  • Intellivision hacks (.cfg files)
  • My Experience Learning 68k Assembly
  • My Atari Projects
  • Writing is hard
  • My Atari 2600 Collection
  • Jodi C. Kirby's blog
  • Power outage a few days ago
  • Sony PlayStation 5/PS5™ Development Kit (Dev Kit) for SALE
  • xNeoGeo1982Blogx
  • The Ivory Tower Collections 7800s
  • Incognito Atari 800 step by step pictorial install tutorial/guide including ATR swap button mod
  • Cree's Stories
  • Testing
  • NeonPeon's (Mark W's) Adventures in programming for Vectrex
  • Stories from the -: ITC :-
  • Gameboy & dress up games
  • BRP's random dev journaling
  • My PC-Engine/TurboGrafx-16 Projects
  • Ivory Tower Technical Notes
  • Programming a game..
  • Games People Play
  • Atari 8-bit Memories, Ideas, and Active Projects
  • WEATHER REPORT
  • Biff's Blasts
  • Programming Journey
  • CREE BENNET DOESN'T CARE
  • Mark W Plays Old Games on a Thursday
  • 35 Years, 9 Months and 16 Days in the Life Of...
  • IntellivisionRevolution's Blog
  • Atari BBS Gurus's News
  • On Duty's Blog
  • The official Robin Gravel's club's Archive
  • Bowling's Blog
  • Lawnmover's Blog
  • Null's null
  • Null's Blog
  • KC-ACE Reboot's KC-ACE Reboot Blog
  • Wizzy's Concept and Theme
  • Wizzy's Form
  • Wizzy's Moodboard
  • Wizzy's Space
  • Wizzy's Magical objects
  • Wizzy's Progress
  • Wizzy's At home
  • Wizzy's Halloween
  • Wizzy's Equipping
  • Wizzy's Mentor
  • Wizzy's World
  • Wizzy's Trials
  • Wizzy's Characters
  • Alternate Reality's Blog

Calendars

  • AtariAge Calendar
  • The Club of Clubs's Events
  • Atari BBS Gurus's Calendar

Product Groups

  • Subscriptions

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Website


Facebook


Twitter


Instagram


YouTube


eBay


GitHub


Custom Status


Location


Interests


Currently Playing


Playing Next

Found 22 results

  1. Anyone here who use/used the p-system and programmed the 99/4A in the Pascal language?
  2. I wrote this library for managing text windows starting in 2015 in the Action! language. The windows have different ornamental controls. I've added features I've dubbed gadgets like radio buttons, regular buttons, checkboxes, progress bars, spinners, and input controls that have type restrictions and scroll if they are larger than displayable space. The gadgets allow building forms which are very close to modern dialogs. I blogged the progress of the library over the years, and over the last couple of months converted the library to C (CC65). I blogged about the C conversion as well. I created full API documentation for both and build some sample apps in each language. The blog has some video demonstrations. Once I completed the C version, I decided to create GitHub repositories for distribution rather than my blog. Maybe someone will find them useful. The C version now includes support for FujiNet, SIO, and APE Time. FujiNet bindings include support for Base64 encode/decode and Hashing using SHA1, SHA256, and SHA512. These updates are not in the Action! library, or the Pascal library. (edit) Amarok converted the C version to Mad-Pascal. I created a corresponding API document, and published it on GitHub. Thanks Amarok! Here are the links: C blog entries: https://unfinishedbitness.info/tag/c-cc65/ C GitHub page: https://github.com/Ripjetski6502/A8CLibrary Action! blog with latest release: https://unfinishedbitness.info/2022/08/27/action-library-v1-51/ Action! blog entries: https://unfinishedbitness.info/2016/04/27/action-windows/ (first post on window library) Action! GitHub page: https://github.com/Ripjetski6502/A8ActionLibrary Mad-Pascal GitHub page: https://github.com/Ripjetski6502/A8MadPascalLibrary Enjoy.
  3. Not MPP or UCSD, but the compiled Pascal for the 990, 980, and the IBM 370. https://dl.acm.org/doi/10.1145/800229.806961 So glad you can download this older stuff from ACM for free now.
  4. Anyone who has ever written an assembly program using the Editor/Assembler package knows the drill. Use the editor to create the source file. Save it as MYFILE:S Run the assembler to convert MYFILE:S to a codefile MYFILE:O. Use the Load and Run to execute the code file. When creating a Pascal program with the p-system, you can do almost exactly the same. The procedure is then, in detail, like this: Press E to start the editor, followed by ENTER to start a new program. Use the editor to type in the source code for your program. Quit the editor, then Write to a filename. Type in myfile and ENTER to save the file. Press Exit to leave the editor. Now press C to compile the program. Type in myfile as the source to compile and $ to create the codefile with the same name. When the compiler has finished, press eXecute to run your program. Enter myfile and it will run your new program. As you can see, this mimics the Editor/Assembler workflow almost exactly. The p-system has another card up its sleeve, though. It's called the workfile. As the name hints, it's the file you are working with. Assuming you don't already have a workfile, the same task as I described above will now run like this: Press E to start the editor, followed by ENTER to start a new program. Use the editor to type in the source code for your program. Quit the editor, then Update to create the workfile and leave the editor. Press Run to execute your program. That's it. The p-system will check if your latest workfile has been compiled. In this case it has not, so it will compile it for you, and then execute it. The next time you select Run, the program will run immediately, as it's already compiled. It should be obvious that the workfile concept saves several keystrokes, when you are creating your program. If you run it and find you want to edit something, you simply invoke the editor and it will open the workfile for you, no questions asked. So, what's the drawback? Well, as long as you are working on one program, and that program fits in one single source file, then none, really. To start a new program, you have to go to the Filer and Save the current workfile under some filename, like myfile. Then you can create a New workfile (also with the filer), exit it and open the editor to enter the text into your new workfile. While in the Filer, you can also check What your current workfile is, and Get any existing file to become the workfile. However, the features inherent in the p-system, some of which I've described in earlier posts, does invite you to create substantial projects. Such projects frequently consist of a main program file, a file to include in the main program file, a file with the source for a separately compiled unit and a file with assembly support for either the unit or the main program. When you have several files like that, the maneuvers to get the correct file to become your current workfile, each time you want to change something, aren't worth it. There's no automation of assembling a source file either. Personally, I never use the workfile. But if you are new with the system, then it's likely that you start by creating software where it works well. A note about filenames. When using the Editor/Assembler, most users adapt some method to tell the difference between the source and object code. They don't have the same file format, so you can tell from that what's what, but you can still not have the same file name for both. My method was usually to name them TEST:S and TEST:O or something similar. With the p-system, although you normally use ten character file names there too, they are really 15 characters long. When you tell the Editor to create the file myfile, it will actually save the file as myfile.text. And when you tell the compiler to compile myfile to the same filename, it will actually compile myfile.text to myfile.code. That's why you can seemingly use the same filename for both the source and the code. They aren't the same, actually. If you did use the workfile in the example above, and then wanted to save it as myfile, you would open the Filer and tell it to save the workfile to myfile. It will then report that it has copied *SYSTEM.WRK.TEXT to MYFILE.TEXT and *SYSTEM.WRK.CODE to MYFILE.CODE.
  5. If you haven't read the threads about memory management for code and data in the p-system, using Pascal, then you should, prior to reading this post. After that, you'll understand that the p-system supports pretty complex software. When writing larger programs, you frequently find that you want to re-use functions you've already written before. To begin with, the p-system already from the beginning contains some such commonly used functions, which you can simply reference in your own program, and then use them just like if you have written the code yourself. In the p-system, this allows you to access some functions that are specific for the 99/4A, like sound processing, sprite handling and character pattern definitions. The standard library To manage this in a simple way, the p-system supports a library function. Programs can be written to be included in a library, which you then can use, even though they aren't inside your own program. The p-system contains a file called *SYSTEM.LIBRARY. Inside that file, which resides on the system disk (*file means a file on the system disk), are the supporting units supplied with the system. The SYSTEM.LIBRARY file contains several units from start. Assume you want to place an asterisk at the center of the screen. This program will do that. program display1; begin gotoxy(20,12); write(chr(42)); end. Now assuming you want a different shape, one that's not available among the standard characters, then you want to redefine the character. The 99/4A does allow for that, but the standard Pascal language has no support for such machine specific things. Here the predefined library function set_pattern comes to resuce. It will do the same things as CALL CHAR in BASIC. Consulting the compiler manual, we find that this function resides in the unit support in the system library. To get access to it is as simple as saying you want to use functions in that library, and then just use it as if it was built into Pascal. program display2; uses support; begin set_pattern(42,'0081422418244281'); gotoxy(20,12); write(chr(42)); end. When the compiler creates the code file from this source code, it will see that you want to use the functions available in the support unit. As you have not told the system where to find support, it will look for it in *SYSTEM.LIBRARY. It is there, so that will work. The compiler will then generate code to define that the routines referred to in support are located in the *SYSTEM.LIBRARY file. When execution comes to set_pattern, an external segment call is done. The operating system will know, from data in the code file, that it needs to load a code segment which is not inside the program running now, but in another file. The support unit will be loaded from the library into memory, where it can be executed. This involves accessing the disk where the library is residing. But all this happens automagically. The only thing needed is the single line uses support in your code. If you have more than one set_pattern call in your program, you'll not notice. Upon the second call, the unit support is already memory resident, so it's called just like a routine in your own program. As you can see, then handling is identical to that of internally declared segments in your own code, which I described in a previous thread. Indeed, as a minimum, each unit in a library is a separate segment. The *SYSTEM.LIBRARY file contains seven units from the beginning. Regardless of how many you use, they are only loaded into memory when needed. Look at this program, which uses two units. program display3; uses support, speech; type longstring = string[255]; procedure waitlong; var i: integer; begin for i:=1 to 32000 do; end; begin gotoxy(20,12); write(chr(42)); waitlong; set_pattern(42,'0081422418244281'); waitlong; say('Hello'); end. The program will first output the * symbol at the center of the screen. It will then spend several seconds in an empty loop. If you are loading the program from a physical diskette drive, the drive will have time to stop. After a while, the drive which contains the *SYSTEM.LIBRARY file will start up, since the program has reached the set_pattern call. The unit support is not in memory at that time, so it requires loading. You'll see the * change shape when this happens. The program will then wait again, long enough for the drive to stop once more. Suddenly, it will start again, when the program reaches the say statement. Unit speech is at this time not loaded, so the access to the library is redone. When it's ready, the computer will speak Hello. If you once again use eXecute to run this program, the sequence will repeat. If you instead use the User restart command, the program will run through the code without starting any diskette drive to load the library routines. User restart preserves the execution environment, incluing loaded internal and/or external segments, so the program can run from start to end without any need for external access of various supporting software. Already as-is, this is a powerful tool to make your programs able to do more things. But it doesn't end there. You can create your own library units, append them to the *SYSTEM.LIBRARY and/or create your own libraries, which can be used in combination with the system's library function. We'll look into that in follow-up posts in this thread.
  6. In another post I described how simple it is to make more efficient use of the small memory available in a standard 99/4A. That post described the handling of data. Now let's look at the program itself. The code pool concept When the p-system is running, it uses all 48 K RAM (32 K CPU RAM and 16 K VDP RAM) for different purposes. VDP RAM is of course used to create the image to display, with character pattern table, display table etc. The remaining part of the VDP memory is used as the primary code pool. That's near 12 Kbytes or so. In the expansion memory, the 8 K part is used solely by the system. Here are the code for the parts of the operating system that can't run from the p-code card, system variables, the 80 column screen and such things. Yes, the p-system normally runs in text mode, 40 columns wide, but by default it simulates an 80 column screen, where you can move the viewport to the right or left, so you can see one half of the screen at each time. Thus by simply writing to the screen, you get these 80 columns simulated with no effort in your own program. The 24 K RAM part is used as the secondary code pool. Code is loaded here if the primary code pool is full, or if the code segment contains TMS 9900 machine code (assembly programs), as they can't execute from the video memory. This part of the memory is also used for the stack. In the post about the data memory I described some use of the stack for data memory allocation. The stack is also used for calulations, tracing subprogram calls and such things. The stack starts at the highest memory location (FFFFH) and grows downwards. At the other end of the 24 K RAM area, the heap is located. The heap is similar to the stack in that it grows and shrinks on demand, but it's different in how it operates. On the stack, new data is allocated on top of what's already there. When data is discarded, it's always removed from the top. On the heap, on the other hand, data is of course originally allocated in the same way. If you allocate ten items, they are added to the heap in that order. The only difference then is that it grows in the other direction, as it starts at A000H and grows upwards. The big difference is that you can remove things from the heap in any order. When you remove something that was created early, a "hole" will appear in the heap. The p-system IV.0 does implement a true heap, not just another stack that's called a heap, like some earlier p-systems did. Thus a hole can be reused, provided the new variable to allocate isn't larger than it can fit in the hole. The p-system can also garbage collect the heap, so it can be packed when needed. The alternate code pool resides in between the heap and the stack. The space available for it hence depends on what's going on in the system. Assuming your program fits in the primary code pool, it will not compete with the stack and heap for space in the 24 K memory area. But if it's larger than what fits in the primary code pool, or if it contains assembly support, then it must be loaded in the secondary pool. In the simplest of these cases, the primary pool is completely unused. That's of course not good. Now we should be aware that the operating system itself may load code in the code pools too, if it can't run that code from the p-code card directly. Fortunately, the PME (p-machine interpreter, the assembly code that executes the p-code) is flexible enough to be able to run p-code from CPU RAM, VDP RAM or even directly from GROM. The p-code on the card itself is stored in GROM chips, so in many cases it can run directly from there. That's the reason for why the 48 K TI 99/4A could run the p-system IV.0, where the Apple II, which also had 48 K RAM, but no p-code card with separate GROM, required an additional 16 K RAM card to be able to run the simpler first versions of the p-system, called Apple Pascal. Code segmentation But how do we make a larger program, that doesn't fit as it is in the primary code pool, to still fit in there, so we can use as much data memory as possible? The p-system's solution to this is called segments. In the p-system, a code segment is a piece of code that must be loaded into memory as a consecutive unit. When there are more than one code pool available, as in the 99/4A, it's an advantage if the largest segment you need to load is smaller than the smallest code pool available, since then the system can always place it where it's most efficient. In Pascal, you can create code segments in your own program, when there's is a benefit to do so. A classic reason is that you have code that runs to set things up before your main program really starts to run, but then never runs again. Or the opposite, code that runs only when the main program is about to stop, to save results in files or whatever. Another typical example can be code that runs only when you are printing results, or when you are inputting data. Have a look at this program. It's a stub that contains a number of different such functions. program doesitall1; type alldata = record (* All things needed *) end; var bigdata: alldata; level: integer; procedure initialize; begin (* Fixes all setup in the bigdata structure *) end; procedure cleanup; begin (* Saves what need to be saved in the bigdata structure *) end; function menu: integer; var temp: integer; begin repeat write('What to do? '); read(temp); until temp in [1..4]; menu := temp; end; procedure dataentry; begin (* Handles user input to the bigdata structure *) end; procedure calculate(complexity: integer); begin for i := 1 to complexity do (* Makes some complex calculations on bigdata *); end; procedure printservice; begin (* generates hardcopy of the things in bigdata *) end; being (* doesitall1 *) initialize; level := 3; repeat case menu of 1: dataentry; 2: calculate(level); 3: printservice; end; until menu=4; cleanup; end. When the main program starts, it begins by a setup procedure. Then it repeatedly calls menu to get the user's choice for what to do. The choice calls a corresponding procedure, until the user quits, in which case a cleanup is done before exiting. In a program like this, everything is loaded as one code segment. If it doesn't fit in the smaller main code pool, it has to compete with stack and heap space in the secondary code pool. Now, assuming it's big enough so that is a problem, how can we handle that? In many systems, like in Extended BASIC, it's possible to run one program from another, so you can overlay code in memory. But data is usually lost when you do it, so it has to be saved manually. In assembly, you can do everything, but that also means that simple things like the menu function above become complex. Forth has other means available, like forgetting definitions and loading other defintions from disk. But you have to manually control that, or define a subsystem that does. If you use Pascal with the p-system, the only thing you need to do is to consider which routines you don't always need. Here, it's pretty simple to see that this list of procedures have one thing in common: They are never needed simultaneously. Initalize Cleanup Dataentry Calculate Printservice Once we have figured that out, we only need to inform the system about it. You do that by telling the compiler which parts of the program can be separate segments in memory. program doesitall2; type alldata = record (* All things needed *) end; var bigdata: alldata; level: integer; segment procedure initialize; begin (* Fixes all setup in the bigdata structure *) end; segment procedure cleanup; begin (* Saves what need to be saved in the bigdata structure *) end; function menu: integer; var temp: integer; begin repeat write('What to do? '); read(temp); until temp in [1..4]; menu := temp; end; segment procedure dataentry; begin (* Handles user input to the bigdata structure *) end; segment procedure calculate(complexity: integer); begin for i := 1 to complexity do (* Makes some complex calculations on bigdata *); end; segment procedure printservice; begin (* generates hardcopy of the things in bigdata *) end; being (* doesitall2 *) initialize; level := 4; repeat case menu of 1: dataentry; 2: calculate(level); 3: printservice; end; until menu=4; cleanup; end. This is all it takes from you. The system will now load only the non-segment parts of the program doesitall2 when you execute it. Immediately, there will be a cross-segment call to initialize. But as a user, you need to do nothing. The operating system will check if segment initialize is in memory. It's not the first time, so it will automatically fetch it from disk and load into an available space in code pool. Then, as you enter your different choices from the menu system, the appropriate cross-segment calls will be made, and the system will load the code as needed. If you first run data entry, then maybe it fits at the same time as initialize remains in memory. If you then do a printout, that part perhaps also fits together with the already loaded segments. When examining the printout, you realize you should return to data entry. In this case, no loading of any segment is done, since the system finds that it's still there, since you used it last time. Now you call calculate. The segment fault (segment is not in memory), which triggers loading the segment, in this case causes a memory fault. The primay code pool is full with other segments, and there's not enough space between the code and the stack in the secondary pool to load the new segment. In this case, the system first attempts to free up more space in the code pool by optimizing the position of the already loaded code. P-code is dynamiclly relocatable, so the system will move code segments around, to make sure they are adjacent, so they occupy a minimal amount of memory. Then it will try to load the missing code segment again. If this faults once again, it will examine the list of currently loaded segments. The system keeps track of whether there is any open call to a segment. If so, it must remain in memory. This means that if one segment calls another, both must be in memory at the same time. But in this case, there are segments that aren't called. Like initialize. The system now checks the segments that are possible to remove. It keeps a simple call history, so the one that hasn't been used for the longest time is sacrificed. In this case, it will be initialize. Eventually, you select to terminate the program, in which case the cleanup segment is loaded. One or more other segments are then removed from memory, if it's necessary to make the cleanup segment fit. As you now hopefully understand, the p-system provides you with quite a complex (at least for its time) system for memory management. You can also see that using this powerful tool is comparatively simple, or even very simple, in your program. The next post on a similar topic will be about separate compilation. It's a very powerful tool, which combines all the memory management features I've described in the first two posts with an ability to write code that's both easier to manage, reuse and debug, in a format where you get all these benefits with very little extra work. There is a reason I've always claimed that the p-system is/was the most comprehensive software development environment for the TI 99/4A!
  7. Today, there are several ways to get way more memory in the TI 99/4A than it had originally. But to use that memory, you have to write programs that manage it. Back in the days, when 32 K RAM was the only memory expansion available, you had to be careful with how you used memory. One way to make that easier was to use the p-system. It was originally developed with a few specific targets in mind. One of them was to be able to run in systems with small memories. Hence the system has a few available functions for that. Data memory If you create a global variable in Pascal, it will exist as long as the program runs. It will occupy memory, regardless of whether you use the variable or not. If it's an integer, using two bytes, that may not matter. But if it's a larger buffer, it's not a good idea. One way could be to declare the variable in a subprogram instead. Compare these two programs. Note that although they are syntactically correct, i.e. they can be compiled without errors, they don't work. Unimportant parts of the logic is just hinted at by comments. program version1; type buftype = packed array[0..1023] of char; mempointer = ^integer; var buffer: buftype; x,y: mempointer; procedure copier(a,b: mempointer); begin (* Use buffer to move data from place pointed to by a to position b *) end; begin (* version1 *) (* Assign addresses to x and y *) copier(x,y); (* Do more things *) end. Here is the other one. program version2; type buftype = packed array[0..1023] of char; mempointer = ^integer; var x,y: mempointer; procedure copier(a,b: mempointer); var buffer: buftype; begin (* Use buffer to move data from place pointed to by a to position b *) end; begin (* version2 *) (* Assign addresses to x and y *) copier(x,y); (* Do more things *) end. The only difference in these two examples is where the variable buffer is declared. But that makes a big difference. In version 1, the variable buffer will occupy one kilobyte of memory all the time. In the second version, on the other hand, buffer will only require that kilobyte as long as procedure copier is running. When it's not, the space is released and can be used for other things. The penalty is a little more time consumed at the call to and return from the subprogram copier. This is one example of how simple it is for the programmer to use the memory management available with Pascal and the p-system. Simply by moving the declaration you can control memory usage.
  8. Update: moved packages to emulation section from software. I have put a together MAME/MESS emulation package that emulates the MyArc Extended BASIC II & TI P-Card for the Ti99. MyarcXBII: MyArc was a company that made peripherals for the TI-99 line. There most famous peripheral (if you want to call it that) was the Geneve. The Geneve was a complete TMS 9995 computer that fit in the TI-99 PEB as a card. Another peripheral that was lesser known, but just as revolutionary, was the MyArc Extended BASIC II. The MyXBII consisted of the 128k or 512k Memory card, a set of disk and a cartridge. When running the MYXBII had 3 times the memory of TIXB, was up to twice as fast as TIXB and was able to access all the graphic capability of the TI graphics card including the hi-rez. If a MyArc HD disk card was added the software could even boot from the MyArc hard drive. It turned the TI99 into a real power house. Unfortunately because of it's expense and the fact that you needed a PEB to run it, the MyArcXBII never really caught on. Now, though, with emulation it cost nothing so through the power of MAME/MESS the power is being released. Start the MyArcXBII at the TI99 main menu by choosing 3-128k BASIC and this will boot the MyArcXBII from the hard drive. P-Card: The P-Card was a card for the PEB that was, more or less, a complete operating system apart from the TI99. It's a virtual machine processor on a card that ran P-Code. It was written totally in software and was based on Pascal and was able to run on other computers that also conformed to the P-Code specifications. It is nothing like a standard TI-99 and when booted takes over the TI-99 and even has a specially formatted disk it uses. There is a complete suite of software and if you can figure it out, kinda nice. To run the P-Card in MAME/MESS click under OPTIONS-DIP SWITCHES then turn on the P-CARD. Hard reboot the machine and the TI-99 will start in the P-Card mode (after a few seconds of beeping and blank pages). To go back to MyArcXBII just turn the P-CARd switch OFF then hard reset the machine. The MAME/MESS package works with any versions of MAME/MESS past version 222. Just merge your version of MAME/MESS into the MESSxxx directory and point the already created batch file in the root to that directory. Package includes manuals, software, batch files and everything you need except MAME/MESS itself. Enjoy. Download from my https://ti99resources.wordpress.com/emulation/ At the bottom of the page is MAME packages, click on MyArc Extended BASIC II to show download files. I have both a package with and without the P-Card. (a truly nice tripped out Ti-99 from mainbyte.com)
  9. Hi together, Kyan Pascal is the best Pascal for Atari ever. We have achieved much progress in restoring the complete developer environment, please see the actual list below. We are still searching for the Toolkit I and II manuals. So, if there is anyone out there in the galaxy, please help us. It is the same with the six million dollar man: Ladies and Gentlemen, we have the capability to rebuild him (here Kyan Pascal), to make Pascal for Atari stronger, faster and better… So, Atari first of the 8 bits… Thank you all so much in advance. P. S. If there is someone in the possession of these manuals, you can send them to me, I OCR them and send you back the manuals. All postage goes to my bill. Already in the can: KIX for the Apple II-Owner's Manual.pdf Kyan Pascal PLUS for the Apple II-Users Manual.pdf Toolkit I.pdf Toolkit II.pdf Toolkit III.pdf and software Toolkit IV.pdf Toolkit V.pdf Update Kyan.pdf Disk Magic.atr Disk Wizard II.atr DOS 2.5 MD.atr Eddy.atr Kyan Pascal (Norwegen).atr Kyan Pascal Kopie.atr Kyan Pascal-original defekt.atr Kyan Pascal.atr Kyan Pascal(defektes_atr)_fix.atr Kyan_Pascal_DOS_2.5_MD_(restored).atr Sherlock V.2.atr Toolkit III.atr Bobs Sector Editor.xex Boot Utility Pack 1.3.xex SHERLOCK V.2.xex DOS 2.0 Modification for special purposes.rtf Kyan Pascal v2.0.rtf Bildschirmfoto 2016-06-18 um 22.41.26.jpg Bildschirmfoto 2016-06-18 um 22.44.14.jpg Bildschirmfoto 2016-06-19 um 21.09.19.jpg Defektes ATR.jpg DIR.jpg editor_1.jpg editor_2.jpg File_A2_OUT_2.jpg File_A2_OUT.jpg Sektor 3B6.jpg Sektor 3C9.jpg Sektor 3CA DUMP.jpg Sektor 373.jpg Apple kyanpas.HDV Apple II stuff Barcardi Kyan_Pascal_Manual_page_01.jpg Kyan_Pascal_Manual_page_02.jpg Kyan_Pascal_Manual_page_03.jpg Kyan_Pascal_Manual_page_04.jpg Kyan_Pascal_Manual_page_05.jpg Kyan_Pascal_Manual_page_06.jpg Kyan_Pascal_Manual_page_07.jpg Kyan_Pascal_Manual_page_08.jpg Kyan_Pascal_Manual_page_09.jpg Holmes Archiv Kyan Pascal 1.1.atr Kyan Pascal A.atr Kyan Pascal B.atr Kyan Pascal - Advanced Graphics Toolkit kyan_toolkit_iii_d7_2.jpg kyan_toolkit_iii_d7.jpg Kyan_Pascal_2.02_(1986) Kyan_Pascal_2.02_(1986)_side_1.atr Kyan_Pascal_2.02_(1986)_side_2.atr Kyan Pascal v2.0.rtf Kyan Pascal Disk 2.02.jpg Kyan_Pascal_2.02.jpg Re- Kyan Pascal-comp.sys.app.textClipping example.tif PASCAL-V2-Cover-Clear.tif Kyan_Pascal_2.02_(1986).zip KYANDSK Neuer Ordner 14 Kyan Pascal(defektes_atr)_fix.atr Toolkit 1-System Utilities Toolkit 2-Mouse Text Toolkit 3-Advanced Graphics Toolkit 4-Turtle Graphics Toolkit 5-Mouse Graphics Toolkit 6-Code Optimizer Toolkit 7-Font Utilities KIX.txt ReadMeKix.txt 2. Kyan Pascal--- -Product.textClipping KYAN PASCAL ADVANC
  10. Hi together, We have made big progress to restore Kyan Pascal (runs on mainframes!) for all: https://atariwiki.org/wiki/Wiki.jsp?page=Pascal#section-Pascal-KyanPascalCopyrightC1985KyanSoftware To complete Kyan Pascal, we need desperately your help again. Best are members of the Kyan team from the golden age, if they read here, too. :-) Anyway, if someone has one of the following things or even know one, who has and can borrow us this for a limited time, please let us know. :-))) The missing list is as follows: - Kyan Pascal version 1.0, 1.2 and 1.3 - Programming Utility Toolkit for Kyan Pascal version 1.x - Advanced Graphics Toolkit for Kyan Pascal version 1.x - Kyan Pascal version 2.0 and 2.03 - System Utilities Toolkit for Kyan Pascal version 2.x - Code Optimizer Toolkit for Kyan Pascal version 2.x ; includes the source code for the Runtime Library Any help of any kind, even just hints or infos to complete the above is very welcome at any time. We really would appreciate your help, because now, we are sadly in a dead end. Only the community is able to bring this to a happy end. Thank you all in advance. :-) Credits so far: We deeply, deeply thank Tom Eckmann, CEO of Kyan Software, for giving Kyan Pascal into PD. Tom, be sure, you are in our hearts forever, you will never be forgotten! Thank you so much! Further, we thank WASEO from Germany for initiating this project, establishing contact to Tom and doing so much for this project. We thank Kevin Savetz for interviewing Tom and making contact again. We thank the "stay behind task force from Abbuc" for founding some ultra rare (way above 10) parts of this projects. We thank GoodByteXL for scanning all the manuals, preparing them, bringing them into read mode and getting into Kyan Pascal that deep, so we could build this site. We thank Thomas Grasel from RAF for borrowing his Kyan Pascal version, so we could compare it with the other versions. We thank Fred from the Atari museum in the Netherlands for a major, lost to believe contribution in this project.
  11. Bill Lange has been blogging about Atari Pascal since early February at https://insideataripascal.blogspot.com/, so here's my own small contribution after spending an afternoon poking around in APX Pascal and looking for the core interpreter. If we look at the PASCAL runtime on the APX Pascal disk, it's a simple enough image. It loads itself from disk to $3300-$59ff and then starts running from $3300. So what does that initial bootstrap code do? Here's the preamble: 3300: A2 00 LDX #0 3302: A9 0C LDA #$0C 3304: 9D 42 03 STA ICCMD,X 3307: 20 56 E4 JSR CIOV 330A: AD A7 33 LDA $33A7 330D: 85 F0 STA $F0 330F: AD A8 33 LDA $33A7+1 3312: 85 F1 STA $F0+1 3314: AD A9 33 LDA $33A9 3317: 85 F2 STA $F2 3319: AD AA 33 LDA $33A9+1 331C: 85 F3 STA $F2+1 331E: AD AB 33 LDA $33AB 3321: 85 F4 STA $F4 3323: AD AC 33 LDA $33AB+1 3326: 85 F5 STA $F4+1 3328: 20 73 33 JSR $3373 This code closes IOCB #0, then sets up $F0-F5 using values at $33A7-$33AC and then calls a subroutine. Those values are: 33A7: 00 3A .WORD $3A00 ; source 33A9: 00 A0 .WORD $A000 ; destination 33AB: 00 20 .WORD $2000 ; count 33AD: 00 1D .WORD $1D00 And the subroutine looks like: 3373: A0 00 LDY #0 3375: B1 F0 LDA ($F0),Y 3377: 91 F2 STA ($F2),Y 3379: A5 F0 LDA $F0 337B: 18 CLC 337C: 69 01 ADC #1 337E: 85 F0 STA $F0 3380: A5 F1 LDA $F0+1 3382: 69 00 ADC #0 3384: 85 F1 STA $F0+1 3386: A5 F2 LDA $F2 3388: 18 CLC 3389: 69 01 ADC #1 338B: 85 F2 STA $F2 338D: A5 F3 LDA $F2+1 338F: 69 00 ADC #0 3391: 85 F3 STA $F2+1 3393: A5 F4 LDA $F4 3395: 38 SEC 3396: E9 01 SBC #1 3398: 85 F4 STA $F4 339A: A5 F5 LDA $F4+1 339C: E9 00 SBC #0 339E: 85 F5 STA $F4+1 33A0: A5 F4 LDA $F4 33A2: 05 F5 ORA $F4+1 33A4: D0 CF BNE $3375 33A6: 60 RTS This is just a block copy routine, which relocates all the code at $3A00-$59FF to $A000-$BFFF. This block of code (which is most of the PASCAL executable), is the actual runtime. A simpler way to do this would have been to use a multi-segment load file, but this works well enough. $A000-$BFFF is the cartridge address space for an 8k cart, so clearly this was intended at one point to be shipped as a cartridge. What happens next: 332B: AD AD 33 LDA $33AD 332E: 85 80 STA $80 3330: AD AE 33 LDA $33AE 3333: 85 81 STA $81 3335: A9 00 LDA #0 3337: 85 82 STA $82 3339: 85 83 STA $83 333B: 20 00 A2 JSR $A200 ... A200: 4C 12 B8 JMP $B812 This copies the word in $33AD ($1D00) to $80,$81 and zeros $82,$83 before invoking a routine at $A200, which vectors to $B812. That routine does several things, including: B834: A5 80 LDA $80 B836: 85 D0 STA $D0 B838: A5 81 LDA $81 B83A: 85 D1 STA $D1 B83C: AD 78 A2 LDA $A278 B83F: 85 CE STA $CE B841: AD 79 A2 LDA $A278+1 B844: 85 CF STA $CE+1 B846: AD 7A A2 LDA $A27A B849: 85 D2 STA $D2 B84B: AD 7B A2 LDA $A27A+1 B84E: 85 D3 STA $D2+1 B850: 20 6B AE JSR $AE6B where: A278: 00 A0 .WORD $A000 A27A: 78 02 .WORD $0278 So we move the word at $80,$81 ($1D00) to $D0,D1, and set $CE,$CF to $A000 and $D2,D3 to $0278, before calling another block copier. AE6B: A0 00 LDY #0 AE6D: A6 D3 LDX $D3 AE6F: F0 0E BEQ $AE7F AE71: B1 CE LDA ($CE),Y AE73: 91 D0 STA ($D0),Y AE75: C8 INY AE76: D0 F9 BNE $AE71 AE78: E6 CF INC $CF AE7A: E6 D1 INC $D1 AE7C: CA DEX AE7D: D0 F2 BNE $AE71 AE7F: A6 D2 LDX $D2 AE81: F0 08 BEQ $AE8B AE83: B1 CE LDA ($CE),Y AE85: 91 D0 STA ($D0),Y AE87: C8 INY AE88: CA DEX AE89: D0 F8 BNE $AE83 AE8B: 60 RTS So we relocate the first $0278 bytes of the "cartridge" to address $1D00-$1F77. The first $200 bytes are just a series of addresses (more on those soon), the next $78 bytes are a set of JMP vectors, e.g. 1F00: 4C 12 B8 JMP $B812 1F03: 4C B1 AB JMP $ABB1 1F06: 4C B6 AB JMP $ABB6 ... 1F72: 4C 87 B8 JMP $B887 1F75: 4C 5F BC JMP $BC5F After we return from this the code continues with: B853: A5 80 LDA $80 B855: 85 82 STA $82 B857: A5 81 LDA $81 B859: 85 83 STA $83 B85B: E6 83 INC $83 B85D: E6 83 INC $83 B85F: 20 EB B9 JSR $B9EB The word at $80,$81 gets moved to $82,$83 and incremented by $200, so the word at $82,$83 is now $1F00. The subroutine called looks like: B9EB: A2 21 LDX #$21 B9ED: A0 00 LDY #0 B9EF: B9 CA B9 LDA $B9CA,Y B9F2: 99 92 00 STA $0092,Y B9F5: C8 INY B9F6: CA DEX B9F7: D0 F6 BNE $B9EF B9F9: A5 81 LDA $81 B9FB: 85 AD STA $AD B9FD: 85 B2 STA $B2 B9FF: E6 B2 INC $B2 BA01: 60 RTS This copies the code at $B9CA into page zero, and patches the value at $81 ($1D) into $AD and the $B2 and then increments $B2, so we end up with the following: 0092: 18 CLC 0093: 65 A4 ADC $A4 0095: 85 A4 STA $A4 0097: 90 0A BCC $00A3 0099: E6 A5 INC $A5 009B: B0 06 BCS $00A3 009D: E6 A4 INC $A4 009F: D0 02 BNE $00A3 00A1: E6 A5 INC $A5 00A3: AD FF FF LDA $FFFF 00A6: 0A ASL A 00A7: B0 05 BCS $00AE 00A9: 85 AC STA $AC 00AB: 6C 00 1D JMP ($1D00) 00AE: 85 B1 STA $B1 00B0: 6C 00 1E JMP ($1E00) This is the core of the Pascal interpreter, similar to the Forth NEXT routine I discussed in http://atariage.com/forums/blog/734/entry-15007-dealer-demo-part-4-some-forth-at-last/. It has three parts, and self-modifies its code as it runs. If you enter at $0092, it increments the current p-code pointer (located at $A4,$A5) by the accumulator. If you enter at $009D, it increments the current p-code pointer by 1. In both cases, it then proceeds to the third part (which can be called directly as well) which reads the p-code value, multiplies the value by two and then patches one of two jump vectors with that value depending on whether the multiply overflowed or not. This allows us to dispatch all 256 possible p-codes, and each code will then jump back into this routine, keeping the interpreter running forever. Of course, we haven't actually gotten into the interpreter yet, only set it up. We'll discuss that in a future post, but we've made decent progress towards separating the runtime from the monitor. In particular, it's clear we could move the 8K runtime in $A000-$BFFF into a cartridge image and modify the PASCAL file to skip the initial relocation and rely on the cartridge. That focuses our attention on the remaining 1.8K of PASCAL to isolate the code that sets up the runtime and loads the MON program. Hopefully we can adapt that code to load another program directly, and thus produce binaries that can run without loading the monitor.
  12. In the last post, we worked through layers of the APX Pascal runtime to find the main interpreter loop, which in fact resides entirely in page zero. In this post, we're going to dig into some of the opcodes to get a flavor for the runtime implementation. As we discussed last time, the each opcode is represented by a JMP value in a 512-byte table that is copied into $1D00 when the runtime starts. If you peruse though the table, the most common JMP target is $B9B5, in 81 entries. This is the not-implemented opcode, hitting any of these in code would be an error. The code seems to be an infinite loop. B9B5: 38 SEC B9B6: A0 00 LDY #0 B9B8: A9 67 LDA #$67 B9BA: 20 EA B8 JSR $B8EA B9BD: 4C B5 B9 JMP $B9B5 The next most common opcode is a 4-way tie, for opcodes $90-$97 ($AA65), $98-9F ($AA7A), $E0-E7 ($A2F5) and $E8-EF ($A8EC). Let's investigate each in turn. AA65: 4A LSR A AA66: 29 07 AND #7 AA68: 48 PHA AA69: A0 01 LDY #1 AA6B: B1 A4 LDA (IP),Y AA6D: 18 CLC AA6E: 65 C8 ADC $C8 AA70: 85 A4 STA IP AA72: 68 PLA AA73: 65 C9 ADC $C8+1 AA75: 85 A5 STA IP+1 AA77: 4C A3 00 JMP $00A3 This appears to be some kind of unconditional branch/jump opcode. The opcode is shifted right and masked, yielding a number 0-3. It then adds this to the value in $C8,C9 plus the value following the opcode. We set the IP to this value and continue execution. AA7A: A8 TAY AA7B: BD 00 06 LDA $0600,X AA7E: E8 INX AA7F: E8 INX AA80: 4A LSR A AA81: B0 03 BCS $AA86 AA83: 98 TYA AA84: 90 DF BCC $AA65 AA86: A9 02 LDA #2 AA88: 4C 92 00 JMP $0092 This pulls the top of data stack (the stack is at $0600 and indexed by X), if it's odd we're done, otherwise we call the branch function above. So it's a conditional branch. Both of these codes are very odd. The only reason I can think of to encode part of the branch offset into the opcode is to extend the range beyond 256 bytes, but in that case, why not just have a separate opcode for long branches. Also, using both BCC and BCS isn't optimal. A little thought shows removing the BCS achieves the same result, but faster. In general the runtime code looks like it could have used a little more optimization. This project started out as a port from the 8080, perhaps the author never developed enough 6502 experience to tighten up the code in the time allowed. The next two routines are similar: A2F5: 29 0F AND #$0F A2F7: A8 TAY A2F8: B1 C6 LDA ($C6),Y A2FA: C8 INY A2FB: CA DEX A2FC: CA DEX A2FD: 9D 00 06 STA $0600,X A300: B1 C6 LDA ($C6),Y A302: 9D 01 06 STA $0601,X A305: 4C 9D 00 JMP $009D and: A8EC: 29 0F AND #$0F A8EE: A8 TAY A8EF: B1 B6 LDA ($B6),Y A8F1: C8 INY A8F2: CA DEX A8F3: CA DEX A8F4: 9D 00 06 STA $0600,X A8F7: B1 B6 LDA ($B6),Y A8F9: 9D 01 06 STA $0601,X A8FC: 4C 9D 00 JMP $009D Both of these routine move a value to the top of the stack, just using different pointers to source the value ($C6 and $B6). Most of the remaining of the opcodes have unique implementations. Some of the interesting ones to look at are "load string" ($2C at $A88F), load small constants ($F0-$F7), load 1, 2 and 4 bytes ($24, $25, $26), call ($A2 at $AB2C) and return ($A6 at $AC96). What's most interesting to me is that having identified these, you might notice they don't match the "Functional Specification" (https://archive.org/details/AtariPascalFunctionalSpecification) at all. Apparently the paper design for the interpreter presented to Atari underwent major revisions by the time it was published. I expected some revisions, but it appears little of the original opcode design survived. In our next post, we'll examine the p-code that exists in the PASCAL runtime object, and write a very basic p-code disassembler.
  13. In the last couple of posts we explored some of the APX Pascal architecture, showing bits of disassembly of the runtime, but I neglected to include the tools I used to extract those bits. This post aims to remedy that, and produce a first draft listing of the APX Pascal runtime. The runtime disassembly was done using similar perl code as I developed in the Dealer Demo Forth deconstruction blog posts last year, so refer to those if you want a discussion on how this disassembler works. There's a few differences worth discussing though. I've split the code into pieces, m6502.pm being generic support for disassembly, pascal.pm being Pascal p-code decompilation and pascal.pl handling working with the PASCAL runtime object from Side 1 of the APX Pascal disk. If you use a perl 5.26 or later you may need to set PERL_USE_UNSAFE_INC=1 in your environment, or add the path with the code to your perl INC path. read_img has been implemented using read_img_core which takes a description of an image. The Dealer Demo version was just a one-off custom piece of code. For apxpascal.pl, the definition is: read_img_core( $addr, $size, '../pascal.xex', [0x06 - 0x3300, 0x3300, 0x59ff], [0x06 + 0x3a00 - 0x3300 - 0xa000, 0xa000, 0xbfff]); which means if you ask for an address between 0x3300 and 0x59ff, start at offset 0x6 of the runtime file. If you ask for an address between 0xa000 and 0xbfff, start at offset 0x706 of the runtime file. The core of the subroutines bytes and words have been factored into bytes_buf and words_buf to allow the code to be used in more cases. Some new options have been added to the core: -str for displaying a string with a known size, -scr for displaying a CR-delimited string. The option -mads, for translating a listing into a MADS compatible source file, is much more sophisticated now. It does some validation of the listing, and converts the listing bytes into a 'check.obx' file. The code is largely the same as the code I've used before when validating OCR's of source code listings (e.g. Atari PILOT or Star Raiders). The code from $A000 to $BFFF is the runtime and is pure assembly code. I produced it by initially disassembling all the code in that region, and then stitching in corrections where data appeared in the stream (usually by noticing a BRK or .BYTE slip in to the disassembly). The version 0.0 documentation (https://archive.org/details/AtariPascalV0.0Documentation) was then used to help pick some label names for common memory locations. I decided to use IP for the pseudo-PC. The commonly location $CC I suspected matched the TMPBASE label from the documentation. $CA was more-or-less exclusively used for saving and restoring the X-register, so XSAVE seemed a natural label (echoes of the Forth VM there). Finally I concluded DR0 must be $B6 (one of 8 16-bit display registers) and LCLBASE (local base register) $C6. $0600 is clearly used as an evaluation stack, so I used EVALPAGE from the 0.0 documentation. I haven't conclusively identified PRGSP, EVALSP, and LEXLEVEL, nor the many temporaries, and the previous labels could prove erroneous, but this is enough for now to produce a more readable listing. The code from $3300 to $39FF is a combination of assembly code and p-code. Whenever a JSR $1F06 appears, some number of JMPs before it appear, followed by what appears to be a length and then a sequence of p-code. A single appearance of JSR $1F03 appears to be followed by an address and then a sequence of p-code. So I decompile decode starting 2 bytes after a JSR $1F03 (until seeing opcode $D9) or $1F06 (until seeing opcode $A6). This description is almost certainly incorrect in some fashion, but seems adequate for now to start decompiling the image. You can find the pascal p-code decompiler in pascal.pm. The decompiler is very simple, it contains a list of p-code instruction lengths. Those that are non-zero are decompiled, the rest are assumed to be errors (not all the values are yet filled in). Negative lengths dump the additional data as words instead of bytes, and opcode $2C is handled as a special case. $2C is clearly a code for a string if you look at examples in the file (e.g. address $3421 contains 0x2c,5,'D:MON'), so clearly a fixed length decompiler isn't going to work for that case. Using this we obtain snippets of p-code like so: 3410: 4C 13 34 JMP *+3 3413: 20 03 1F JSR $1F03 3416: 3A 34 .WORD $343A 3418: A2 .BYTE $A2 3419: 21 35 .WORD $3521 341B: FD 09 .BYTE $FD,$09 341D: 25 .BYTE $25 341E: 3A 34 .WORD $343A 3420: F1 .BYTE $F1 3421: 2C .BYTE $2C 3422: 05 44 3A .BYTE 5,'D:MON' 3425: 4D 4F 4E 3428: A2 .BYTE $A2 3429: E0 36 .WORD $36E0 342B: 25 .BYTE $25 342C: 3A 34 .WORD $343A 342E: F1 .BYTE $F1 342F: A2 .BYTE $A2 3430: 7D 35 .WORD $357D 3432: 25 .BYTE $25 3433: 3A 34 .WORD $343A 3435: F1 .BYTE $F1 3436: A2 .BYTE $A2 3437: 64 35 .WORD $3564 3439: D9 .BYTE $D9 and so: 36DD: 4C 00 00 JMP $0000 36E0: 4C E3 36 JMP *+3 36E3: 20 06 1F JSR $1F06 36E6: 56 00 .WORD $56 36E8: A8 00 .BYTE $A8,$00 36EA: D2 .BYTE $D2 36EB: BC 51 .BYTE $BC,$51 36ED: 09 52 .BYTE $09,$52 36EF: 09 54 .BYTE $09,$54 36F1: 01 54 .BYTE $01,$54 36F3: A8 00 .BYTE $A8,$00 36F5: BC 10 .BYTE $BC,$10 36F7: A6 .BYTE $A6 We need to assign identifiers to those opcodes (first bytes) to make this more readable, but we can do that later as we better identify the opcodes. The current decompilation and the tools are attached to this post. In my next post we'll continue examining the opcodes and improving the listing. pascal1.zip
  14. The last blog entry introduced the tools I'm using to explore the Pascal runtime, and included a preliminary (i.e. rough) disassembly. Now we'll start refining that disassembly and start discussing more of the opcodes. Firstly, the last listing was erroneous around $B959 to $B991. There are strings there I somehow missed when spot checking the disassembly, so I've fixed up that part of the disassembly. There were also a couple of missing $9B's as well after strings, and the p-code disassembly had a couple of errors as well which I've now fixed. Now let's discuss some more opcodes. The simplest opcode in the listing is opcode DB. It is just: AF9D: E8 INX AF9E: E8 INX AF9F: 4C 9D 00 JMP NEXT_OP1 Since X is the current evaluation stack pointer, and it grows downwards, this opcode drops the topmost entry of the stack, so let's call it DROP. Another simple opcode is $DA, which disassembles as: AF8C: CA DEX AF8D: CA DEX AF8E: BD 03 06 LDA EVALPAGE+3,X AF91: 9D 01 06 STA EVALPAGE+1,X AF94: BD 02 06 LDA EVALPAGE+2,X AF97: 9D 00 06 STA EVALPAGE,X AF9A: 4C 9D 00 JMP NEXT_OP1 This adds one entry to the stack, and copies the (previous) top element to it, so we can call this DUP. Opcode D2 is a bit longer, but just involves moving things around the stack, so that the first two elements are exchanged, so let's call it SWAP. AF5F: BC 00 06 LDY EVALPAGE,X AF62: BD 02 06 LDA EVALPAGE+2,X AF65: 9D 00 06 STA EVALPAGE,X AF68: 98 TYA AF69: 9D 02 06 STA EVALPAGE+2,X AF6C: BC 01 06 LDY EVALPAGE+1,X AF6F: BD 03 06 LDA EVALPAGE+3,X AF72: 9D 01 06 STA EVALPAGE+1,X AF75: 98 TYA AF76: 9D 03 06 STA EVALPAGE+3,X AF79: 4C 9D 00 JMP NEXT_OP1 Some other simple stack-only opcodes are 30 (AND), 32 (OR), 34 (NOT), 36 (EOR), 38 (NEG), 40 (ADD) and 44 (SUB). All of these replace the top two values on the stack with the result of the operation. Opcodes 60 and 70 oddly point to the same code, which looks like this: B185: BD 01 06 LDA EVALPAGE+1,X B188: DD 03 06 CMP EVALPAGE+3,X B18B: D0 5C BNE $B1E9 B18D: BD 00 06 LDA EVALPAGE,X B190: DD 02 06 CMP EVALPAGE+2,X B193: D0 54 BNE $B1E9 B195: F0 5F BEQ $B1F6 ... B1E9: E8 INX B1EA: E8 INX B1EB: A9 00 LDA #0 B1ED: 9D 00 06 STA EVALPAGE,X B1F0: 9D 01 06 STA EVALPAGE+1,X B1F3: 4C 9D 00 JMP NEXT_OP1 B1F6: E8 INX B1F7: E8 INX B1F8: A9 01 LDA #1 B1FA: 9D 00 06 STA EVALPAGE,X B1FD: A9 00 LDA #0 B1FF: 9D 01 06 STA EVALPAGE+1,X B202: 4C 9D 00 JMP NEXT_OP1 If the top two values are equal, we replace them with a 1, otherwise we replace them with a 0. So let's call them EQU. Opcodes 62 and 72 reverses this, so let's call them NEQ. Now why are there two equivalent opcodes? Well, let's look at opcode 64 and 74. 64 is simply: B1A9: 20 2F BE JSR $BE2F B1AC: F0 3B BEQ $B1E9 B1AE: 30 39 BMI $B1E9 B1B0: 10 44 BPL $B1F6 and 74 is similar: B1C9: 20 2F BE JSR $BE2F B1CC: F0 1B BEQ $B1E9 B1CE: 90 19 BCC $B1E9 B1D0: B0 24 BCS $B1F6 with BE2F: BD 02 06 LDA EVALPAGE+2,X BE32: DD 00 06 CMP EVALPAGE,X BE35: F0 0B BEQ $BE42 BE37: BD 03 06 LDA EVALPAGE+3,X BE3A: FD 01 06 SBC EVALPAGE+1,X BE3D: 09 01 ORA #1 BE3F: 70 0A BVS $BE4B BE41: 60 RTS BE42: BD 03 06 LDA EVALPAGE+3,X BE45: FD 01 06 SBC EVALPAGE+1,X BE48: 70 01 BVS $BE4B BE4A: 60 RTS BE4B: 49 80 EOR #$80 BE4D: 09 01 ORA #1 BE4F: 60 RTS This difference here seems to be whether the 16-bit comparisons here are done signed or unsigned. The 6x opcodes are signed comparisons, and the 7x opcodes are unsigned comparisons. 60 is EQU and 70 is UEQU, which happen to have identical implementations, and 62 and 72 are similarly NEQ and UNEQ. 64, 66, 68 and 6A seem to be greater than (GT), less than (LT), greater than or equal (GTE) and less than or equal (LTE) respectively. 74, 76, 78 and 7A appear to be same, only unsigned. To further complicate matters, the 8x opcodes also implement comparisons (the same six EQU, NEQ, GT, LT, GTE, LTE operations), but for other types than signed and unsigned integers. The second byte after determines the type, with 00 => bool, 01 => string (both from the stack, so both of these sequences consume 2 bytes), and 02, 03 and 04 being various byte comparisons consuming an additional 2 bytes after the type byte. So our simple p-code disassembler which assumes all opcodes but 2C are fixed size needs to be modified to handle these opcodes a little differently. That's enough for this post. The runtime disassembly is certainly starting to make a bit more sense, but there are plenty of mysteries left to explore. pascal3.zip
  15. Created a little package for MAME/MESS that enables MyArcXBII and P-Card in one pre-made package. Just add latest MAME/MESS and go. It's on my project page that accesses my https://ti99resources.wordpress.com/:
  16. I finally got Turbo Pasc99 running. I created a small program to print “Hello World”. It compiles fine so I compiled It to DSK1.TEST. So how do I convert this to a program and run it? I would prefer to create program files that can be used with just TIPI, I think that is an EA5 file? When I load “test” into the editor, I can see what looks like assembly language to me. Do I use the Assembler next?
  17. I have been testing the waters of Atari APX Pascal recent and have been having an issue with MEDIT blowing up when run from the Pascal menu. I twittered the great Bill Lange who gave me the fix. (1) As you probably know, you have to copy the MEDIT executable over to your work disk image in disk drive D2. In addition, MEDIT needs a minor modification for it to work with the Atari Pascal Language System. (2) With DOS loaded, put the work disk into D1. Use the DOS menu option N to create a MEM.SAV file on the work disk. (3) Using the DOS menu option L, BINARY LOAD MEDIT using the /N (MEDIT/N) option to prevent it from running. This will write to the MEM.SAV file on the work disk. (4) Using the DOS menu option K, BINARY SAVE it back as follows: MEDIT/A, 2600, 2601. This append operation tells the Pascal program point to begin execution at the MEDIT entry point. (5) Put the work disk back in D2. Put APLS Disk #1 in D1. You should now be able to launch MEDIT from the Atari Pascal Monitor. the twitter conversation: https://twitter.com/BillLange1968/status/1087211748921434113 Thanks, Bill Lange
  18. Hi together, We have made big progress to restore Kyan Pascal (runs on mainframes!) for all: https://atariwiki.org/wiki/Wiki.jsp?page=Pascal#section-Pascal-KyanPascalCopyrightC1985KyanSoftware To complete Kyan Pascal, we need desperately your help again. Best are members of the Kyan team from the golden age, if they read here, too. :-) Anyway, if someone has one of the following things or even know one, who has and can borrow us this for a limited time, please let us know. :-))) The missing list is as follows: - Kyan Pascal version 1.0, 1.2 and 1.3 - Programming Utility Toolkit for Kyan Pascal version 1.x - Advanced Graphics Toolkit for Kyan Pascal version 1.x - Kyan Pascal version 2.0 and 2.03 - System Utilities Toolkit for Kyan Pascal version 2.x - Code Optimizer Toolkit for Kyan Pascal version 2.x ; includes the source code for the Runtime Library Any help of any kind, even just hints or infos to complete the above is very welcome at any time. We really would appreciate your help, because now, we are sadly in a dead end. Only the community is able to bring this to a happy end. Thank you all in advance. :-) Credits so far:We deeply, deeply thank Tom Eckmann, CEO of Kyan Software, for giving Kyan Pascal into PD. Tom, be sure, you are in our hearts forever, you will never be forgotten! Thank you so much! Further, we thank WASEO from Germany for initiating this project, establishing contact to Tom and doing so much for this project. We thank Kevin Savetz for interviewing Tom and making contact again. We thank the "stay behind task force from Abbuc" for founding some ultra rare (way above 10) parts of this projects. We thank GoodByteXL for scanning all the manuals, preparing them, bringing them into read mode and getting into Kyan Pascal that deep, so we could build this site. We thank Thomas Grasel from RAF for borrowing his Kyan Pascal version, so we could compare it with the other versions. We thank Fred from the Atari museum in the Netherlands for a major, lost to believe contribution in this project.
  19. I'm programming a little card game in Pascal. Card games in Pascal are fun programming exercises but are generally not visually interesting. I'm looking at changing up the UI to show cards being dealt, presented, flipped. I looked into turtlegraphics, but I'm thinking I'll use sprites. If for no other reason than because I have access to far more documentation on sprites than turtlegraphics. Sprites will make it a non-portable Pascal program, but my goal in doing this wasn't to create a portable Pascal program. The current text UI version of the code is portable to any UCSD system, save for the random number generator. I found some pseudo-random-number generators that I believe could be easily implemented, so that's likely a problem easily solve-able. I'm just going for a little visual improvement. With all of that as a preamble, here's my question. It's been a long time since I coded sprites, so I'm creating some test cases to model out the things I'll need to do for this to work. My test moves a double-sized sprite (not magnified) from (y=95,x=128) at velocity (y=-8, x=0) for a countdown of 64, then a velocity of (y=-4,x=0) for a countdown of 64. Then it holds position. I'm just experimenting with showing a card come out fast, then slow down, then stop. (Inspired by the truly beautiful motion of the Q*Bert demo we saw at the Evanston meet-up a few weeks ago!) I'd expect the sprite to end up at 95 + ((-8/32*64) + (-4/32*64)), or y=71, x=128. It isn't. It's ending up at double the distance: y=47, x=128. The velocity/32 every 60th of a second math comes from page 145 of the Pascal Compiler manual. This suggests a sprite travels just about 2 pixels every 60th of a second. Or, assuming it's an octal and not a decimal clock, 1 / 32 * 64 == 2. The Editor/Assembler manual has a different description on sprite motion. Page 341 says, that a velocity of >01 causes a sprite to move one pixel every 16/60th. Assuming that the velocity is the same, it seems to me that the assembler manual says we get 4 pixel moves every (roughly) 60th of a second. Back to our octal clock, 16/64 == 4. If I'm reading this right, the sprite speed in the assembler manual would describe the 2x difference in velocity that I'm seeing with where my sprite is ending up. I haven't run all possible tests yet to figure out if I'm just thick-headed. I haven't coded sprites in assembly or XB routines to time comparisons, I haven't re-timed using a standard sized sprite, etc. But anyone who is familiar with sprite motion who knows the velocity I should expect, I would appreciate it. Best regards, R.
  20. Hi together, we have some problems regarding Kyan Pascal. Here: https://atariwiki.org/wiki/Wiki.jsp?page=Pascal we have place everything available regarding Pascal, but the numbering of the Kyan Pascal versions seems to be wrong. We assume 1.0 and 1.1 in 1985 and 2.x in 1986, but we are not sure. How knows more and may help the community to come around the problem? We know for sure, that Kyan just delivered SD-disks only. The MD-version from atarionline.pl is with help from GoodbyteXL total restored and now playable in Altirra and other emulators. From Atarimania we know of Toolkit III: Atari Advanced Graphics, is the truth somewhere out there? Does anyone have an image of that? Thank you all very much in advance. All the best.
  21. I had the following post on planet-99.net - can anyone offer any advice...
  22. I've noticed that there are a number of qualified users hanging around here. I've also realized that I have a package of software which is focused on disk controller access. I wrote it once to be able to make myself a working copy of disks like Miller's Graphics Explorer and Advanced Diagnostics. They were copy protected, so they weren't possible to copy with conventional means, not even by a sector copier. Thus I wrote some software to analyze and copy disks which use odd sector numbers or unformatted storage. Today, in the world of simulators, this is of course more or less pointless. But I've understood that some still have working 99/4A hardware and some may be more interested in system programming than games. So the question I'm posing is if there is any point at all in me spending time to copy these files to a format that can be hosted so you can see it? The assembly part of the software package concerns low level reading and writing of disk tracks and sectors. Since writing tracks is the same as formatting, there's also an application which can format disks inside the p-system environment. Originally, you had to use the Disk Manager or similar to accomplish that. There is a dformat program, that comes with the p-system, but it can't handle double density disks. Neither can it handle the different sector interlacing which is optimal for the p-system, which is faster in reading files than the normal operating system. Then there an upper level, written in Pascal, which concerns analyzing read tracks and creating new tracks to be written (formatted). It also concerns reading and writing sectors on the disk. Note that the details concern the CorComp disk controller, which is pretty similar to the one from TI, but does use a different floppy disk controller chip, so it's not identical.
×
×
  • Create New...