; 20221210 bkw: reverse-engineered "source" for setmem.xex. ; originally created with da65 (cc65's disassembler), then ; hand-edited to make it (hopefully) more human-readable. ; By default, this builds the original setmem.xex, 877 bytes, ; md5sum f7834eaf50e8b5d5314a20f6a5d83a0d. ; I've added a couple of optional defines: ; reverse_logic - For upgrades that have 256K/compy as the default. ; coldstart - Reboot the Atari instead of exiting to DOS. For use ; with SpartaDOS X, which crashes if we exit to DOS ; after changing the mode. ; See the Makefile for build options. .include "atari.inc" .include "xex.inc" .include "inv.inc" ; 2 byte ZP pointer used for printing text. msgptr = $cc ; "Magic" hardware register. On an un-upgraded Atari, $d3f3 is just ; a "mirror" of $d303 (aka PBCTL). It's special on the tfhh upgrade ; though: changing it to $d303 here results in a non-functional setmem.xex. ; Also note that writing to $d3f3 only affects the upgrade if the ; Start key is pressed... and even when Start is pressed, writing ; to $d3f3 still changes PBCTL. magic_register = $d3f3 loadaddress = $3000 xex_org loadaddress entrypoint: cld ; unnecessary. lda #$08 sta CONSOL ; clicks the consol speaker (no idea why). lda #$00 sta choice ; choice = 0 (but it immediately gets inc'd to 1). next_choice: inc choice ; choice++; lda choice cmp #$03 bne choice_ok lda #$00 ; if(choice == 3) choice = 0; sta choice choice_ok: lda #banner_msg sta msgptr+1 jsr print_msg lda choice clc asl a asl a tay ; Y = choice * 4; lda msg0,y sta msgptr lda msg0+1,y sta msgptr+1 lda magicbits_0,y sta magic_bits jsr print_msg read_consol: lda CONSOL and #$07 cmp #$03 beq option_pressed cmp #$06 beq start_pressed cmp #$05 bne read_consol select_pressed: lda CONSOL and #$07 cmp #$07 bne select_pressed beq next_choice option_pressed: lda #no_change_msg sta msgptr+1 print_and_exit: jsr print_msg lda #$00 tax tay rts ; apply the current choice to the hardware start_pressed: sei ; disable IRQs lda #$00 sta NMIEN ; disable NMIs lda magic_register and #$FC ora magic_bits sta magic_register wait_consol_release: lda CONSOL and #$07 cmp #$07 bne wait_consol_release lda #$40 sta NMIEN ; re-enable NMIs cli ; re-enable IRQs .ifdef coldstart jmp COLDSV .else lda #mode_set_msg sta msgptr+1 jmp print_and_exit .endif ; print null-terminated ATASCII message pointed to by (msgptr). print_msg: lda #$00 tax tay sta ICBLL,x sta ICBLH,x lda #PUTCHR sta ICCOM,x lda msgptr sta ICBAL,x lda msgptr+1 sta ICBAH,x nextchar: lda (msgptr),y beq call_cio iny bne zptr_hi_ok inc msgptr+1 zptr_hi_ok: inc ICBLL,x bne nextchar inc ICBLH,x bne nextchar call_cio: jmp CIOV ; R/W data (2 bytes): choice: .byte $00 ; Currently chosen option (default 1, range 0 to 2). ; This gets set to one of disable_magic, compy_magic, or rambo_magic. ; Bits 0 and 1 will get ORed into magic_register. magic_bits: .byte $00 ; R/O data (rest of file): disable_magic = $01 .ifdef reverse_logic compy_magic = $00 rambo_magic = $02 .else compy_magic = $02 rambo_magic = $00 .endif ; Table of 3 4-byte entries, one per choice. 4th byte is filler (always 0). msg0: .addr disable_msg magicbits_0: .byte disable_magic filler_0: .byte 0 msg1: .addr compy_msg magicbits_1: .byte compy_magic filler_1: .byte 0 msg2: .addr rambo_msg magicbits_2: .byte rambo_magic filler_2: .byte 0 ; Rest of the data is messages to be printed to IOCB#0 by print_msg. ; These are null-terminated. banner_msg: .byte CLS .byte EOL inverse " Setup tool for tfhh SRAM expansions " .byte EOL,EOL .ifdef reverse_logic inverse "Reverse Logic" .byte " - This" .else .byte "20210614" .byte " - This tool" .endif .byte " works with:" .byte EOL,EOL .byte "- 512 KB SRAM memory expansion " inverse "V4.5" .byte EOL .byte " (please check revision number!)" .byte EOL,EOL .byte "- 576 KB SRAM memory expansion " inverse "V2" .byte EOL .byte " (only for the Atari 600XL, please" .byte EOL .byte " check the presence of " .byte '"', "V2", '"', " printed", EOL .byte " on the PCB)" .byte EOL,EOL .byte "Use console key " inverse " SELECT " .byte " to change" .byte EOL .byte "the desired mode, press " inverse " OPTION " .byte " to" .byte EOL .byte "quit this tool without any change" .byte EOL .byte "or press " inverse " START " .byte " to setup the SRAM" .byte EOL .byte "memory expansion as shown and" .byte EOL .ifdef coldstart inverse "reboot" .byte " the Atari." .else .byte "return to DOS." .endif .byte EOL,EOL .byte "Expansion will be set to: " .byte EOL,EOL .byte "==> " .byte 0 disable_msg: inverse " Memory Expansion switched off" .byte 0 compy_msg: inverse " 256 KByte Compy-Shop/XE mode" .byte 0 rambo_msg: inverse " 512 KByte RAMBO mode" .byte 0 mode_set_msg: inverse " " .byte EOL,EOL .byte "Mode was set. Program terminated." .byte EOL,EOL,0 no_change_msg: inverse " " .byte EOL,EOL .byte "Nothing changed. Programm terminated." .byte EOL,EOL,0 xex_run entrypoint