From 4eed9a32708361fbd21747a934950ef4e99ba94e Mon Sep 17 00:00:00 2001 From: flowenol Date: Wed, 10 Mar 2021 10:48:58 +0100 Subject: [PATCH] Fast loader and bugfixes in firmware --- README.md | 26 +++--- src/cartridge.a65 | 208 ++++++++++++++++++++++++++++++++++---------- src/rom_content.a65 | 5 +- 3 files changed, 180 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index a939bc3..6151eef 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,29 @@ This repository contains firmware files for the "Apple-1 RAM/ROM Cartridge" expa ## Description -This project aims to provide Apple-1 users with a quick way to expand RAM capacity in their systems up to 52 KB and to simultaneously store some Apple-1 programs in -~30KB of on-board ROM, which can be banked in and out via software. The on-board ROM also contains a loader program which is capable of loading programs spanning across noncontinuous memory locations. +This project aims to equip Apple-1 users with a quick way to expand RAM capacity in their systems up to 52 KB and to simultaneously +store Apple-1 programs in ~30KB of on-board ROM, which can be banked in and out via software. The on-board ROM also contains a loader +program which is capable of loading programs spanning across noncontinuous memory locations. You can either use a default loader program `4000R`, which displays the list of all available program entries, or the fast loader program `4300R`, which loads the +specific program entry automatically. -The A1C expansion card allows via the physical switch to completely disable the ROM/loader program functionality which takes up to the 2 KB of memory (`$4000-$47FF`) -and to provide continuous 44KB wide RAM address space instead. +The A1C expansion card allows to completely disable the ROM/loader functionality (via physical switch) which takes up to 2 KB of +memory (`$4000-$47FF`) and to provide continuous 44KB wide RAM address space instead (`$1000-$BFFF`). ## Memory map -Physical switch in ROM mode: +With physical switch in ROM mode: | address | function | | --- | --- | +| `$0000` | program entry to load via the fast loader program | | `$1000-$3FFF` | RAM region #1 | | `$4000` | the start address of the on-board loader program | +| `$4300` | the start address of the fast loader program | | `$47F8-$47FF` | write to these memory locations causes ROM to be banked in or out depending on the least significant bit of the address, A0=0 - ROM banked out, A0=1 - ROM banked in | | `$4800-$BFFF` | RAM region #2 when ROM banked out | | `$4800-$BFFF` | ROM with program contents when ROM banked in | -Physical Switch in RAM mode: +With physical switch in RAM mode: | address | function | | --- | --- | @@ -37,14 +41,15 @@ The contents of this repository are as following: * inc/ - contains Apple-1 programs in binary format, the package is downloadable [here](https://drive.google.com/file/d/1G0ycKSszlr45RE8Rp6eW-0qxz4MS9qDN/view?usp=sharing) * mapping/ - contains EQN and JED files for GAL22V10 based address decoder * scripts/ - a bunch of useful python scripts which allow conversion from binary to Woz monitor format and vice versa -* src/ - contains the 6502 assembly sources for the Apple-1 RAM/ROM Cartridge onboard ROM loader program +* src/ - contains the 6502 assembly sources for the on-board ROM loader programs ## Requirements -You need the following to successfully build the firmware: +You need the following to successfully build and install the firmware: * [xa](https://www.floodgap.com/retrotech/xa/) cross assembler * Some software capable of translating the EQN files into JED's. I used for this purpose the DOS based EQN2JED from OPALjr PLD Development Package. This is only required if you wish to make some changes to the GAL based address decoder. The default JED file should be fine for most users. +* EEPROM programmer. I used [TL866](http://autoelectric.cn/EN/TL866_main.html) programmer for this purpose. ## How to build? @@ -58,7 +63,8 @@ And to clean the build: # How to customise? -In order to customise your ROM contents you have to edit the `src/rom_content.a65` source file. You can find the entry table structure documentation in the source file. +In order to customise your ROM contents you have to edit the `src/rom_content.a65` source file. You can find the entry table structure +documentation in the source file. Maximum of 99 entries is allowed, anything above that will be ignored. ## PCB @@ -76,6 +82,6 @@ http://github.com/flowenol/applesoft-lite ## How to install hardware? Just put the board in right orientation (as marked on the PCB) in the Apple-1 expansion slot. -Or you can use the port expander if the on board slot is already occupied: +Or you can use the port expander if the expansion slot on the Apple-1 board is already occupied: https://github.com/flowenol/Apple1ExpanderPcb diff --git a/src/cartridge.a65 b/src/cartridge.a65 index 5d729ec..0a27e9b 100644 --- a/src/cartridge.a65 +++ b/src/cartridge.a65 @@ -22,17 +22,22 @@ #define str_addr $40 ; entries scanning variables -#define entries_counter $42 -#define entries_scan_addr $43 -#define entry_segments $45 -#define entry_to_load $46 +#define entries_number $42 +#define entries_counter $43 +#define entries_counter_bcd $44 +#define entries_scan_addr $45 +#define entry_segments $47 +#define entry_to_load $48 ; jmp addr variable -#define jmp_addr $47 +#define jmp_addr $49 -; option select variables -#define option_data $49 -#define key_data $50 +#define key_data $4B + +#define option_data $00 + +#define entries_per_page $14 +#define max_entries $63 * = $4000 @@ -44,17 +49,49 @@ start ; enable rom bank sta rom_bank - ; print entries and get option + ; only 99 entries allowed + lda rom_content + cmp #max_entries + bcc store_entries_count + lda #max_entries + +store_entries_count + sta entries_number + +show_entries + ; print entries and get option - X contains number of digits jsr print_entries +input jsr get_option + ; check number of digits - if not zero then validate option, + ; otherwise print next page or repeat + txa + bne validate_option + + ; check if all entries have been printed + lda entries_counter + cmp entries_number + + ; if yes - repeat + beq show_entries + + ; else continue printing pages + jsr print_entry + jmp input + +validate_option ; option validation lda option_data - beq start + ; invalid - user typed "0" or "00" + beq show_entries - cmp rom_content + cmp entries_number + ; valid - last entry beq valid_option - bpl start + + ; invalid out of range + bcs show_entries valid_option lda option_data @@ -252,6 +289,7 @@ print_entries ; init entries counter lda #$00 sta entries_counter + sta entries_counter_bcd ; init entries scan addr lda #choose_next_str + sta str_addr+1 + jsr print_str + rts + print_entries_done ; print choose string lda #choose_str sta str_addr+1 jsr print_str - rts print_str @@ -349,56 +405,66 @@ print_str_loop bne print_str_loop rts -; prints only numbers in range 0-19 -print_number - lda #$09 - cmp $00,X - bmi greater_than_nine - lda $00,X +print_number_bcd + pha + clc + and #$F0 + rol + rol + rol + rol + rol + beq print_next_digit jsr prhex - jmp print_number_done -greater_than_nine - lda #$01 + +print_next_digit + pla + and #$0F jsr prhex - ; save number in Y - lda $00,X - tay - ; decrement 10 - lda #$09 - sta $00,X - tya - sbc $00,X - jsr prhex - ; restore number from Y - tya - sta $00,X + print_number_done rts +entries_page_hit + lda entries_counter +entries_page_loop + cmp #entries_per_page + beq entries_page_end + bcc entries_page_end + sec + sbc #entries_per_page + jmp entries_page_loop +entries_page_end + rts + + ;;; printing-end ;;; get-option + get_option - ; init digits counter + ; stores option number in option_data, digits count in X + ; init digits counter in X ldx #$00 get_key ; wait for key lda kbd_cr bpl get_key lda kbd_data + and #$7F ; store key data sta key_data ; if CR check if option is satisfied - cmp #$8D ; CR + cmp #$0D ; CR beq get_key_done ; check range 0-9 - cmp #$B0 ; 0 + cmp #$30 ; 0 bmi get_key - cmp #$BA ; 9 + cmp #$3A ; 9 bpl get_key ; which digit we are processing? @@ -416,7 +482,7 @@ one_digit ; ??? sec lda key_data - sbc #$B0 + sbc #$30 sta option_data echo_key @@ -446,7 +512,7 @@ two_digit_inc_done ; compute int value from second digit sec lda key_data - sbc #$B0 + sbc #$30 ; and store in option_data sta option_data @@ -461,10 +527,6 @@ two_digit_inc_done jmp echo_key get_key_done - ; if CR was pressed as the first key, then simply omit - txa - beq get_key - ; print CR lda #$8D ; CR jsr echo @@ -481,6 +543,7 @@ increment_16bit increment_16bit_done rts +;; adds A to ZP address in X add_to_addr clc adc $00,X @@ -497,6 +560,57 @@ add_to_addr_done welcome_str .byt $15,$0D,"AVAILABLE OPTIONS:",$0D,$0D choose_str .byt $0F,$0D,"CHOOSE OPTION:" +choose_next_str .byt $27,$0D,"CHOOSE OPTION (PRESS RETURN FOR NEXT):" loader_end + +* = $4300 +.dsb (*-loader_end), $FF + +* = $4300 +fast_loader_start = $4300 + + ; clear decimal mode + cld + + ; enable rom bank + sta rom_bank + + ; only 99 entries allowed + lda rom_content + cmp #max_entries + bcc store_entries_count_fast + lda #max_entries + +store_entries_count_fast + sta entries_number + +validate_option_fast + ; option validation + lda option_data + beq invalid_option_fast + cmp entries_number + beq valid_option_fast + bcs invalid_option_fast + + ; load entry +valid_option_fast + sta entry_to_load + jmp load_entry + +invalid_option_fast + ; print choose string + lda #wrong_option_str + sta str_addr+1 + jsr print_str + + jmp monitor + + +wrong_option_str .byt $0F,$0D,"WRONG OPTION",$0D,$0D + +fast_loader_end + #include "src/rom_content.a65" diff --git a/src/rom_content.a65 b/src/rom_content.a65 index 4909563..9ae114c 100644 --- a/src/rom_content.a65 +++ b/src/rom_content.a65 @@ -1,5 +1,5 @@ * = $4800 -.dsb (*-loader_end), $FF +.dsb (*-fast_loader_end), $FF ; start of loader entry table section @@ -9,7 +9,7 @@ rom_content = $4800 ; define the number of available entries number_of_entries .byt $08 -; entry srtucture +; entry structure ; number of segments - byte ; ; repeat for each segment: @@ -171,6 +171,7 @@ count10_3_cont_start .word count10_fix_cont count10_str .byt $13,"COUNT TO 10 (ASOFT)" count10_jmp_addr .word $7DF4 + ; end of loader entry table section ; start of binary content section