bugbiter Posted May 6, 2015 Share Posted May 6, 2015 I'm tired of pressing option to boot without basic. Why can't a program do that for itself when starting? I just added lda #243 sta portb as the first statements in a XEX's init block. That should disable basic, keep OS ROM and normal RAM bank for subsequent main program load. Init code block is $3E00-$3FED. Under SpartaDOS 3.3 I get some strange behaviour - black screen and infinite key click sound. I'm not in the mood for intense debugging so I just ask you guys..Whats wrong with my idea? Quote Link to comment Share on other sites More sharing options...
+CharlieChaplin Posted May 6, 2015 Share Posted May 6, 2015 (edited) Well, i am not a programmer, so I have no idea. But, errm, Bill Wilkinson was one of the authors of Atari Basic and also author of the book "Inside Atari Basic" - and he released a short utility in Compute! magazine, named "BASOFF.COM". This utility has a length of only 57 bytes, it uses page 4 to switch off Atari Basic, right after that page 4 is available again... (maybe you want to disassemble this utility and see what it does or just use it)... BASOFF.XEX Edited May 6, 2015 by CharlieChaplin Quote Link to comment Share on other sites More sharing options...
+Stephen Posted May 6, 2015 Share Posted May 6, 2015 I am pretty sure you want to do a lda portb and %11111101 sta portb This leaves PORTB intact, and only turns off bit 1 (BASIC enable). Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 6, 2015 Share Posted May 6, 2015 Bit 1 is a BASIC disable bit, so: lda #1 sta $03F8 ; basicf lda $D301 ora #$02 sta $D301 lda #$C0 sta $6A ; ramtop Setting BASICF and RAMTOP avoids any nasties. Quote Link to comment Share on other sites More sharing options...
phaeron Posted May 7, 2015 Share Posted May 7, 2015 You'd also have to reopen E: as BASOFF.XEX does to actually relocate screen memory upward.... but yes, it's nicer for programs to auto-disable BASIC instead of requiring users to do it manually. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted May 7, 2015 Share Posted May 7, 2015 Here's the disassembly. I can't quite understand the need to open E: in mode 12, then set RAMTOP, then open E: again in mode 3. org $0400 ; L0400: lda PORTB ora #$02 sta PORTB lda #$01 sta BASICF lda #$0C jsr OpenE lda #$C0 sta RAMTOP lda #$03 OpenE: sta IOCB0+ICCOM lda #<Name sta IOCB0+ICBAL lda #>Name sta IOCB0+ICBAH ldx #$00 jmp CIOV Name: .byte "E:" .byte $00 ; org $02E2 ; .word L0400 ; Quote Link to comment Share on other sites More sharing options...
+JAC! Posted May 7, 2015 Share Posted May 7, 2015 (edited) I've updated the corresponding section in the Atari 8-bit Programming Tips and Recommendations http://www.wudsn.com/index.php/productions-atari800/tutorials/tips EDIT: hehe, concurrent post. My version uses a bit shorter code for E: and only re-opens it, if RAMTOP was not yet correct. This way it does not flicker if somebody already did press OPTION before. Edited May 7, 2015 by JAC! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 7, 2015 Share Posted May 7, 2015 Here's the disassembly. I can't quite understand the need to open E: in mode 12, then set RAMTOP, then open E: again in mode 3. org $0400 ; L0400: lda PORTB ora #$02 sta PORTB lda #$01 sta BASICF lda #$0C jsr OpenE lda #$C0 sta RAMTOP lda #$03 OpenE: sta IOCB0+ICCOM lda #<Name sta IOCB0+ICBAL lda #>Name sta IOCB0+ICBAH ldx #$00 jmp CIOV Name: .byte "E:" .byte $00 ; org $02E2 ; .word L0400 ; It doesn't open the editor twice. The first call to "OpenE" passes the CIO close channel code in the accumulator, so it's a close/open sequence. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted May 7, 2015 Share Posted May 7, 2015 It doesn't open the editor twice. The first call to "OpenE" passes the CIO close channel code in the accumulator, so it's a close/open sequence. Thanks, I didn't know 12 $0C was close. I looked through the CIO stuff in Mapping, and must have missed it. Quote Link to comment Share on other sites More sharing options...
1050 Posted May 7, 2015 Share Posted May 7, 2015 Pg. 88. Easy to miss when there is so much to look thru. Quote Link to comment Share on other sites More sharing options...
Kyle22 Posted May 7, 2015 Share Posted May 7, 2015 I found it deep in the IOCB section. For the ICCOM field, the following values apply (BASIC XIO commands use the same values): Command Decimal Hex ---------------------------------------------------------------------- Open channel 3 3 Get text record (line) 5 5 BASIC: INPUT #n,A Get binary record (buffer) 7 7 BASIC: GET #n,A Put text record (line) 9 9 Put binary record (buffer) 11 B BASIC: PUT #n,A Close 12 C Dynamic (channel) status 13 D Quote Link to comment Share on other sites More sharing options...
bugbiter Posted May 8, 2015 Author Share Posted May 8, 2015 Hmm.. it's not working right. The init code block turns basic off all right, but after the main program is loaded, Basic is back on. It seems SpartaDos turns it back on during continued loading. It's using RAM under the OS, right? So it sure meddles with portB.. I simply switch off Basic again in the main program, that's done the trick.. Quote Link to comment Share on other sites More sharing options...
Gury Posted January 9, 2020 Share Posted January 9, 2020 Little off-topic... I am still not 100% sure if Mad Pascal disables BASIC on program run or not. I checked the programs which use memory addresses beyond $A000 for storage data, but all of them work in text mode 0 with no additional call to InitGraph (I still have to test those examples on real hardware). I experimented with other modes by calling InitGraph procedure, which consequently blocked the usage of this area (I couldn't store values there anymore). Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 9, 2020 Share Posted January 9, 2020 Possibly it does dynamic storage allocation for stuff like stacks and arrays? Fair chance it doesn't play with the Basic switching, especially if it came out before 1984. You could probably work it out if you had a compiled program then try it in various configurations in emulation. Quote Link to comment Share on other sites More sharing options...
thorfdbg Posted January 9, 2020 Share Posted January 9, 2020 On 5/8/2015 at 9:38 PM, bugbiter said: Hmm.. it's not working right. The init code block turns basic off all right, but after the main program is loaded, Basic is back on. On the XL operating system and Os++, this is normal if you run through a reset. The state of the basic switch is stored in address $3f8. The byte at this address shall be non-zero to enforce that the Basic ROM stays disabled after going through the reset vector. On a second matter, it is in general not sufficient to switch basic off just before the binary starts. You need to turn it off before the binary loads. That is, you need to prepend a small code to the actual that is run through the init-vector of the dos loader, which turns basic off both through PIA Port B, through the BasicDisabled flag at $3f8, then adjusts memtop, then re-opens the editor, then continues loading. This is because a binary may well use addresses above $a000 to load to, and this would fail if Basic would be still on during loading. 2 Quote Link to comment Share on other sites More sharing options...
E474 Posted January 9, 2020 Share Posted January 9, 2020 Hi, won't RAMTOP be wrong on a 16K 600XL? Am asking in context of a boot disk rather than XEX, though I think this would also apply to code after $2000. Quote Link to comment Share on other sites More sharing options...
baktra Posted January 9, 2020 Share Posted January 9, 2020 3 hours ago, E474 said: Hi, won't RAMTOP be wrong on a 16K 600XL? Am asking in context of a boot disk rather than XEX, though I think this would also apply to code after $2000. It would wrong, of course. There would need to be certain logic checking the RAMTOP and adjusting it. On the other hand, software that really needs RAM below BASIC wouldn't work on a computer with less than 48 KB RAM anyway. Quote Link to comment Share on other sites More sharing options...
Gury Posted January 10, 2020 Share Posted January 10, 2020 21 hours ago, thorfdbg said: On a second matter, it is in general not sufficient to switch basic off just before the binary starts. You need to turn it off before the binary loads. That is, you need to prepend a small code to the actual that is run through the init-vector of the dos loader, which turns basic off both through PIA Port B, through the BasicDisabled flag at $3f8, then adjusts memtop, then re-opens the editor, then continues loading. Thanks for info! I was not aware of the flag at $3f8. Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 10, 2020 Share Posted January 10, 2020 If the program knows that the machine won't reboot then it can be easier to just set the flag at $3F8 and call a warmstart $E474 - then the OS takes care of the memory management and proper E: stuff. Quote Link to comment Share on other sites More sharing options...
baktra Posted January 10, 2020 Share Posted January 10, 2020 (edited) There is also one thing specific to the CC65 and its ATARI target and runtime library. It is, to my surprise, using MEMTOP to position its C runtime stack, though it is documented. So, for this specific situation, adjusting MEMTOP is also needed, even though it is a vector used by BASIC. I didn't do it in the TRAIN 2 game and its loading screen gets a little glitch (P letter appears briefly on screen). Apart from the glitch, there is no other damage, fortunately. A circumvention is to boot with the OPTION key pressed. Edited January 10, 2020 by baktra Quote Link to comment Share on other sites More sharing options...
Rybags Posted January 10, 2020 Share Posted January 10, 2020 MEMTOP is maintained by the OS and will be set when E: or S: is OPENed, pointing to the byte before the start of the Display List. APPMHI ($E,$F) is the pointer that applications, languages and programs should use to tell the OS the highest address it should not use - a screen open that violates it will fail. The 800 OS has a bug where if you set it above where the default Gr. 0 DList would appear then do a warmstart, the machine will become unrecoverable since E: can't open so no input is possible. The XL OS has a check for this condition and will adjust APPMHI to allow E: to function normally if an open fails on warmstart. A common mistake some people make is adjusting RAMTOP based on it's "current" value which can cause Basic programs to have memory creep issues. The proper way is to use RAMSIZ ($2E4) as the reference to the actual top of RAM then adjust RAMTOP from that value. 1 Quote Link to comment Share on other sites More sharing options...
baktra Posted January 10, 2020 Share Posted January 10, 2020 1 hour ago, Rybags said: MEMTOP is maintained by the OS and will be set when E: or S: is OPENed, pointing to the byte before the start of the Display List. APPMHI ($E,$F) is the pointer that applications, languages and programs should use to tell the OS the highest address it should not use - a screen open that violates it will fail. The 800 OS has a bug where if you set it above where the default Gr. 0 DList would appear then do a warmstart, the machine will become unrecoverable since E: can't open so no input is possible. The XL OS has a check for this condition and will adjust APPMHI to allow E: to function normally if an open fails on warmstart. A common mistake some people make is adjusting RAMTOP based on it's "current" value which can cause Basic programs to have memory creep issues. The proper way is to use RAMSIZ ($2E4) as the reference to the actual top of RAM then adjust RAMTOP from that value. Thanks. I didn't know. In my program, I do not re-open the E: device (I just close it as I don't use it later). Quote Link to comment Share on other sites More sharing options...
Gury Posted January 10, 2020 Share Posted January 10, 2020 Here is Mad Pascal code which writes two consequent bytes to $A000 area even if BASIC is still ON. It does use code from JAC!'s page. I only removed program starting address setting and error trapping in case $A000 cannot be written to. Program runs in graphics mode 12 and shows results in text area (reading default values and then writing new values). program testmem; uses graph, crt; const ram = $a000; var mem : array [0..0] of byte; begin asm { LDA #$c0 ;Check if RAMTOP is already OK CMP $6a ;This prevent flickering if BASIC is already off BEQ RAMOK STA $6a ;Set RAMTOP to end of BASIC STA $2E4 ;Set RAMSIZ also LDA $d301 ;Disable BASIC bit in PORTB for MMU ORA #$02 STA $d301 LDA #$01 ;Set BASICF for OS, so BASIC remains OFF after RESET STA $3f8 LDX #2 ;Close "E:" before re-openining it again JSR EDITOR LDX #0 ;Open "E:" to ensure screen is not at $9C00 EDITOR LDA $e401,x ;This prevents garbage when loading up to $bc000 PHA LDA $e400,x PHA RAMOK }; InitGraph(12); mem := pointer(ram); Writeln('Read $A000 = ', mem[0], ' $A001 = ', mem[1]); mem[0] := 1; mem[1] := 2; Writeln('Write $A000 = ', mem[0], ' $A001 = ', mem[1]); repeat until keypressed; end. 1 Quote Link to comment Share on other sites More sharing options...
thorfdbg Posted January 10, 2020 Share Posted January 10, 2020 8 hours ago, Rybags said: If the program knows that the machine won't reboot then it can be easier to just set the flag at $3F8 and call a warmstart $E474 - then the OS takes care of the memory management and proper E: stuff. Too late. Remember, a program may want to load into the $a000 area, thus at the time you run through warmstart, the conflict already happened. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.