******************************************************************************** * TILDA 64k ROM Wrapper * 2-16-2019 TAT * Working as of 2-17-2019 @ 1:46am. However... 4k copies make for wretched play * 2/22 All TI mode components removed. Banking handled via mapper. * 2/24 Corruption disappered. No idea why. * 2/25 Joystick code fixed. Endless loops don't end * 2/26 Pete integrated Geneve key routine and Vid/Sound addresses into build * 2/27 Mapper code updated for EQUate >1800 * 2/28 Cleanup * 3/1 MEM XOP ISSUE; mapped 8000 space manually * * Left to do: * - Add geneve trampoline code to base and remove from loader (Pete) * - Implement video mode save * - Exit routine: restore video, turn off sound Gens, release memory * - Try to reduce memory map pagecount *------------------------------------------------------------------------------- WS EQU >F020 my workspace * MAIN3 LWPI WS LET'S LOAD OUR WORKSPACE LIMI 0 turn off those interrupts! BL @TTYOUT Give user a title DATA TITLE1,0 CLR R0 Begin setting up for extra memory XOP @MEM,0 get free pages CI R1,9+8 want 15 pages for load JL BYBY if fewer available, exit.. LI R0,1 get pages (R1 holds number available for our use) LI R2,8 ;1 8 VIRTUAL page 8 (pagetable starts AFTER 64K) CLR R3 Any RAM is ok XOP @MEM,0 get the RAM ABS R0 error? JEQ MEMOK no BYBY BL @TTYOUT memory error - report it! DATA NOMEM,0 B @EXIT MEMOK LI R0,4 get the memory table LI R1,PGETBL and put it into the page table LI R2,100 this is overdoing it for 2Meg system, but who cares XOP @MEM,0 do it! LI R0,3 LI R1,4 LI R2,4 XOP @MEM,0 *********************** * GET THE FILE FROM CLI * * parse routine from who knows where... at least it works * LI R0,>3200 50 bytes for WORK length LI R1,WORK-1 patch it MOVB R0,*R1+ crunch command line and move it to WORK MOV @>0128,R2 get command line argument address JEQ NOGOT if no arguments CB @2(R2),@-1(R1) see if command line is too long JHE NOGOT if too long MOV R1,R5 else save address of WORK to R5 DEC R5 to length pointer MOVB @2(R2),R6 argument length SRL R6,8 make it a word INCT R6 add two NXTNOD MOV R2,R3 save command address INCT R3 add 2 MOV R2,R4 AI R4,8 GETNOD MOVB *R3+,*R5+ start moving the data DEC R6 till count is done JEQ GOTCMD C R3,R4 r3 holds node count JL GETNOD if done this node, go get some more MOV *R2,R2 get next node JMP NXTNOD * GOTCMD MOVB @WORK-1,R1 length of argument JEQ NOGOT if no arg SRL R1,8 else make it a word INC R1 and add 1 for the loop conter LI R2,40 largest filename possible LI R4,WORK address of command line text GETFIL CB *R4+,@H32 look for a space in the command line (filename) JLE GOTFIL if ASCII 0-32, we have the filename DEC R1 don't have it yet, count down JEQ NOGOT we done with arguments? DEC R2 we done with the 40 possible bytes of filename? JNE GETFIL NOGOT BL @TTYOUT DATA USAGE,0 B @EXIT * GOTFIL SETUPTHEPARSE CLR R0 we have the filename, now put a null at end DEC R4 back to the previous byte MOVB R0,*R4 then write a null LI R0,8 parse the filename LI R1,WORK get logical filename from here LI R2,LEN+1 and put hardware name in the pab CLR R3 what the hell is an alias prefix? XOP @UTIL,0 go do the parse * * Finished Parsing name. Now try to load it. * BL @TTYOUT DATA OPENING,0 MOVB @LEN+1,@DMD+3 BL @TTYOUT DMD DATA FNAME,0 display name BL @TTYOUT DATA CRLF2,0 LI R0,FILE XOP @IO,0 call Geneve file IO XOP MOVB @FILE+2,R1 check for an error JEQ GOODFILE2 wrong file, incorrect size, etc BL @TTYOUT show the error DATA IOERR,0 JMP EXIT * EXIT BL @TTYOUT normal exit DATA CRLF2,2 with a CRLF LI R0,>06 RELEASE MDOS MEMORY LI R1,1 XOP @MEM,0 BLWP @0 Thank MDOS for working so well, then exit ; EXIT, stage left ; ; 1. Shut down sound regs ; 2. Reset video ; 3. Release memory (above) TILDEX LI R0,1 ; restore video mode (need to save it earlier) ; XOP @VIDEO,0 JMP EXIT ; File found and loaded. Let's start our patching ; map the first page of the image. Place in 0x2000-0x3fff bank GOODFILE2 LI R4,MAPTILDA From memory map starting at >10000 (1st page about 64K MOVB *R4+,@>F111 get a page of data ;Set TI Mode via CRU bits LIMI 0 ; LI R12,>1EE0 9640 cru ; SBZ 1 9995 DEC OFF ; SBO 10 9640 MODE (1EF4) ; patch/replace tilda trampoline routine in all 8 banks with a BRANCH to ours LI R0,MAPTILDA PGETBL+8 LI R1,8 8 pages NEXTB1 MOVB *R0+,@>F112 get a page MOV @TRAMP2,@>402A overwrite TILDA trampoline MOV @TRAMP2+2,@>402C with a branch instruction to tramp DEC R1 JNE NEXTB1 ; Start Tilda. Must prime bank 0 via trampoline STARTILDAG CLR R12 Ensure SBO 2 vid int enabled ; SBZ 25 SBO 25 enable vdp wait states LI R12,>1EFE SBZ 0 enable ram wait states ; Clear pattern/color table extended address registers LI R0,>0800 BL @VDPREG LI R0,>0900 BL @VDPREG LI R0,>0A00 BL @VDPREG LI R0,>0B00 BL @VDPREG LI R0,>0C00 BL @VDPREG LI R0,>0D00 BL @VDPREG LI R0,>0E00 BL @VDPREG ; Tilda VDP registers from Faire release ; Warning: VR#1 MSBit should be 0 for V9938 but seems to be working ; ; LI R0,>0000 ; BL @VDPREG ; LI R0,>0162 Tilda: E2 ; BL @VDPREG ; LI R0,>0200 ; BL @VDPREG ; ; LI R0,>030D ; BL @VDPREG ; LI R0,>0401 ; BL @VDPREG ; LI R0,>0507 ; BL @VDPREG ; LI R0,>0602 ; BL @VDPREG ; LI R0,>07F1 ; BL @VDPREG LI R0,MAPTILDA MOVB *R0,@>F113 prime the mapper, or address >600E is unknown! ; MOVB @PGETBL+4,@>F114 MAP 8000 SPACE. THX XOP LI R0,>6000 bank 0 ; MOV @>600E,R1 recode this to pick address from ROM header ; MOV @>600C,R1 MOV @>6006,R1 get pointer to title INCT R1 point to branch address MOV *R1,R1 dynamic B @TRAMP VDPREG MOVB @>F021,@>F102 ORI R0,>8000 MOVB R0,@>F102 RT *=========================================== ; Geneve mapper / bank switcher ; TRAMPX EQU >1800 PGETBL EQU >1802 256 bytes for the page map MAPTILDA EQU PGETBL+8 0x10000, page 1 beyond visible 64k range ;TRAMPX DATA 0 We will save R0 to keep it pristine TRAMP MOV R0,@TRAMPX ANDI R0,>001F 0,2 [6000,6002, etc] SRL R0,1 4; /2 for bank # AI R0,MAPTILDA get pagelist offset MOVB *R0,@>F113 0X6000 MOV @TRAMPX,R0 B *R1 TRAMP2 B @TRAMP ;USED TO PATCH IMAGE ************************** * MDOS write tty routine * ************************** TTYOUT MOV *R11+,R8 get data address MOV *R11+,R9 get length of data to write MOV R9,R2 save length in r2 for the ttyout routine LI R10,WORK for the move to hi memory MOV R10,R1 save for the ttyout routine TTY1 MOVB *R8+,*R10+ move em to hi memory JEQ TTY2 if we hit a null DEC R9 till r3 is zero JNE TTY1 TTY2 LI R0,>0027 do the actual ttyout routine XOP @VIDEO,0 B *R11 *===================================== * end of code, data follows * NOMEM TEXT '* Insufficient Memory - 136K required' BYTE >0D,>0A,0 EVEN OPENING BYTE 13,10,10 TEXT 'Loading ' BYTE 0 TITLE1 BYTE 13,10,10 TEXT 'Legend of Tilda 64k wrapper (28Feb2019tt) BYTE 0 USAGE BYTE 13,10,10,9 TEXT 'Usage: TILDG 64k-image' BYTE 13,10,0 IOERR BYTE 13,10 TEXT '* File Error' BYTE 13,10,10,0 CRLF2 BYTE 13,10,0 *cr/llf combo for ttyout H32 BYTE >20 HFF BYTE >FF KEY DATA 5 keyboard XOP VIDEO DATA 6 video xop MEM DATA 7 memory manager xop IO DATA 8 i/o xop UTIL DATA 9 utility xop * 8 x 8k = 64k x 4 = 256 sectors FILE DATA >0A00,>0001,0,>0000,0,0,256 Geneve PAB; BREAD opcode LEN DATA >0028 * --> status byte / length byte FNAME EQU $ WORK EQU FNAME+300+200+10+50 *--------------------------------------------------------- ; BSS 8192 0 ; BSS 8192 2 ; BSS 8192 4 ; BSS 8192 6 ; BSS 8192 8 END