]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
New command: cfboot - boot from cf card.
authorLeo C <erbl259-lmu@yahoo.de>
Thu, 9 Jun 2016 00:20:50 +0000 (02:20 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Thu, 9 Jun 2016 00:20:50 +0000 (02:20 +0200)
avr/Tupfile
avr/cmd_boot.c
avr/command_tbl.c
z180/Makefile
z180/Tupfile
z180/cfboot.180 [new file with mode: 0644]
z180/config.inc

index 9f9537672386bd8133e86b046f7508359dd9387d..0eb910acd450541a899efa2d931ce0a55cfae95c 100644 (file)
@@ -22,7 +22,7 @@ SRC           += ../time/system_time.c ../time/set_system_time.c
 
 ASRC   += ../time/system_tick.S
 
-SRC_Z          = ../z180/hdrom.c
+SRC_Z          = ../z180/hdrom.c ../z180/cfboot.c
 
 #TARGETS       = $(PROG).elf
 
@@ -110,8 +110,8 @@ LDFLAGS     += -Wl,--cref
 !SIZE = |> ^ SIZE^ $(SIZE) %f |>
 
 : foreach $(ASRC) |> !as |>  {objs}
-: foreach $(SRC) | ../z180/hdrom.h |> !cc |>  {objs}
-: $(SRC_Z) |> !cc -D'const=const __flash' |> {objs}
+: foreach $(SRC) | ../z180/hdrom.h ../z180/cfboot.h |> !cc |>  {objs}
+: foreach $(SRC_Z) |> !cc -D'const=const __flash' |> {objs}
 
 : {objs} |> !LINK |> $(PROG).elf
 : $(PROG).elf |> !OBJCOPY |> %B.hex
index 73f2cf3e19c1999027e7fda1c6eb222e6952fb3c..b00d0628f9077c01c7acf54ea1d6deb416117904 100644 (file)
@@ -20,6 +20,7 @@
 #include "cli.h"                       /* run_command() */
 #include "env.h"
 #include "con-utils.h"
+#include "getopt-min.h"
 #include "z80-if.h"
 #include "z180-serv.h" /* restart_z180_serv() */
 #include "debug.h"
 /* ugly hack to get Z180 loadfile into flash memory */
 #define const const FLASH
 #include "../z180/hdrom.h"
+#include "../z180/cfboot.h"
 #undef const
 
 
 
-static void z80_load_mem(void)
+static void z80_load_mem(int_fast8_t verbosity,
+                               const FLASH unsigned char data[],
+                               const FLASH unsigned long *sections,
+                               const FLASH unsigned long address[],
+                               const FLASH unsigned long length_of_sections[])
 {
-       unsigned sec = 0;
-       uint32_t sec_base = hdrom_start;
-
-       printf_P(PSTR("Loading Z180 memory... \n"));
-
-       while (sec < hdrom_sections) {
-               printf_P(PSTR("   From: 0x%.5lX to: 0x%.5lX    (%5li bytes)\n"),
-                               hdrom_address[sec],
-                               hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
-                               hdrom_length_of_sections[sec]);
-
-               z80_write_block_P((const FLASH unsigned char *) &hdrom[sec_base],  /* src */
-                               hdrom_address[sec],                  /* dest */
-                               hdrom_length_of_sections[sec]);      /* len */
-               sec_base+=hdrom_length_of_sections[sec];
-               sec++;
+       uint32_t sec_base = 0;
+
+       if (verbosity > 1)
+               printf_P(PSTR("Loading Z180 memory... \n"));
+
+       for (unsigned sec = 0; sec < *sections; sec++) {
+               if (verbosity > 0) {
+                       printf_P(PSTR("   From: 0x%.5lX to: 0x%.5lX    (%5li bytes)\n"),
+                                       address[sec],
+                                       address[sec]+length_of_sections[sec] - 1,
+                                       length_of_sections[sec]);
+               }
+
+               z80_write_block_P((const FLASH unsigned char *) &data[sec_base],  /* src */
+                               address[sec],                  /* dest */
+                               length_of_sections[sec]);      /* len */
+               sec_base += length_of_sections[sec];
        }
 }
 
@@ -64,13 +71,206 @@ command_ret_t do_loadf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
                my_puts_P(PSTR("Bus timeout\n"));
                return  CMD_RET_FAILURE;
        }
-       z80_load_mem();
+       z80_load_mem(2, hdrom,
+                               &hdrom_sections,
+                               hdrom_address,
+                               hdrom_length_of_sections);
+
        z80_bus_cmd(Release);
 
        return CMD_RET_SUCCESS;
 }
 
 
+void print_vars(char *title)
+{
+       uint8_t buf[5];
+       zstate_t state = z80_bus_state();
+
+       if((state & ZST_ACQUIRED) == 0)
+               z80_bus_cmd(Request);
+
+       z80_read_block(buf,     9, sizeof buf);
+
+       if((state & ZST_ACQUIRED) == 0)
+               z80_bus_cmd(Release);
+
+       printf_P(PSTR("%s: stage: %d, flag: 0x%.02x, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
+                               title, buf[0], buf[1], buf[2], buf[3], buf[4]);
+}
+
+
+/*
+ *  bootcf [options]
+ *
+ *             -a      address                 (100h)
+ *             -s      start sector    (0)
+ *             -c      sector count    (7)
+ *             -i      Partition id    (52)
+ *             -n  load only
+ *             -t      timeout                 (10000)
+ *             -v      verbose
+ */
+
+command_ret_t do_bootcf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       struct {
+               uint8_t  jr[2];
+               uint16_t loadaddr;
+               uint8_t  sec_start;
+               uint8_t  sec_cnt;
+               uint8_t  part_id;
+               uint16_t timeout;
+               uint8_t  stop_stage;
+       } boot_param;
+
+       struct {
+               uint8_t  stop_stage;
+               uint8_t  done;
+               uint8_t  result;
+               uint8_t  ide_stat;
+               uint8_t  ide_error;
+       } boot_res;
+
+       int_fast8_t verbosity = 0;
+       uint8_t stages;
+       uint32_t val;
+
+       (void) cmdtp; (void) flag;
+
+       /* get default values */
+       memcpy_P(&boot_param, cfboot, sizeof boot_param);
+       stages = boot_param.stop_stage;
+
+       /* reset getopt() */
+       optind = 0;
+
+       int opt;
+       while ((opt = getopt(argc, argv, PSTR("vna:s:c:t:i:"))) != -1) {
+               switch (opt) {
+               case 'v':
+                       verbosity++;
+                       break;
+               case 'n':
+                       if (boot_param.stop_stage > 0)
+                               boot_param.stop_stage--;
+                       break;
+               case 'a':
+                       val = strtoul(optarg, NULL, 16);
+                       if (val < 0x100 || val > 0xFE00) {
+                               printf_P(PSTR("Address out of range: 0x%.4lX\n"), val);
+                               return CMD_RET_FAILURE;
+                       }
+                       boot_param.loadaddr = val;
+                       break;
+               case 's':
+                       val = strtoul(optarg, NULL, 16);
+                       if (val > 255) {
+                               printf_P(PSTR("Start sector out of range: 0x%lX\n"), val);
+                               return CMD_RET_FAILURE;
+                       }
+                       boot_param.sec_start = val;
+                       break;
+               case 'c':
+                       val = strtoul(optarg, NULL, 16);
+                       if (val > 127) {
+                               printf_P(PSTR("Sector count out of range: 0x%lX\n"), val);
+                               return CMD_RET_FAILURE;
+                       }
+                       boot_param.sec_cnt = val;
+                       break;
+               case 't':
+                       val = strtoul(optarg, NULL, 10);
+                       if (val < 0x1 || val > 0xFFFF) {
+                               printf_P(PSTR("Timeout value out of range: 0x%lX\n"), val);
+                               return CMD_RET_FAILURE;
+                       }
+                       boot_param.loadaddr = val;
+                       break;
+               case 'i':
+                       val = strtoul(optarg, NULL, 16);
+                       if (val < 0x01 || val > 0xFF) {
+                               printf_P(PSTR("Partition id out of range: 0x%lX\n"), val);
+                               return CMD_RET_FAILURE;
+                       }
+                       boot_param.part_id = val;
+                       break;
+               default: /* '?' */
+                       return CMD_RET_USAGE;
+               }
+       }
+
+       /* remaining arguments */
+       argc -= optind;
+       if (argc) {
+               my_puts_P(PSTR("Argument error!\n"));
+               return CMD_RET_USAGE;
+       }
+
+       if ((val = (uint32_t) boot_param.loadaddr + boot_param.sec_cnt * 512) >= 0xFF00) {
+               printf_P(PSTR("Top address out of range: 0x%.4lX\n"), val);
+               return CMD_RET_FAILURE;
+       }
+
+
+
+       if (z80_bus_state() & ZST_RUNNING) {
+               my_puts_P(PSTR("CPU is allready running!\n"));
+               return CMD_RET_FAILURE;
+       }
+       if (!(z80_bus_cmd(Request) & ZST_ACQUIRED)) {
+               my_puts_P(PSTR("Bus timeout\n"));
+               return  CMD_RET_FAILURE;
+       }
+       z80_load_mem(verbosity, cfboot,
+                               &cfboot_sections,
+                               cfboot_address,
+                               cfboot_length_of_sections);
+
+       z80_write_block((const uint8_t *) &boot_param,
+                               cfboot_address[0], sizeof boot_param);
+       z80_bus_cmd(Release);
+
+       if (boot_param.stop_stage == 0) {
+               printf_P(PSTR("Bootloader loaded at: 0x%.4X\n"), (uint16_t) cfboot_address[0]);
+       } else {
+               printf_P(PSTR("Executing %d of %d Bootloader stages...\n"),
+                               boot_param.stop_stage, stages);
+
+               z80_bus_cmd(Run);
+               z80_bus_cmd(Release);
+
+               clear_ctrlc();          /* forget any previous Control C */
+               for (boot_res.done = 0; boot_res.done != 0xFF;) {
+                       _delay_ms(8);
+                       /* check for ctrl-c to abort... */
+                       if (had_ctrlc() || ctrlc()) {
+                               break;
+                       }
+                       z80_bus_cmd(Request);
+                       z80_read_block((uint8_t *) &boot_res,
+                                       cfboot_address[0]+sizeof boot_param - 1, sizeof boot_res);
+                       z80_bus_cmd(Release);
+               }
+
+               if (boot_res.done != 0xFF) {
+                       z80_bus_cmd(Reset);
+                       my_puts_P(PSTR("Abort\n"));
+               } else {
+                       if (boot_param.stop_stage == stages) {
+                               my_puts_P(PSTR("Booting...\n"));
+                       } else {
+                               z80_bus_cmd(Reset);
+                               printf_P(PSTR("Bootloader stopped at stage %d, result: %d, IDE stat/error: 0x%.02x/0x%.02x\n"),
+                                       boot_param.stop_stage - boot_res.stop_stage,
+                                       boot_res.result, boot_res.ide_stat, boot_res.ide_error);
+                       }
+               }
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
 command_ret_t do_busreq_pulse(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        uint16_t count=1;
index 944c1c4b0dcbbf5e5286168ed4ce645d91372471..7ebc008f804cadc27f31834f4bba90a8bdf15ebf 100644 (file)
@@ -16,6 +16,7 @@ extern command_ret_t do_env_default(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_env_set(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_env_save(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_loadf(cmd_tbl_t *, int, int, char * const []);
+extern command_ret_t do_bootcf(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_loadcpm3(cmd_tbl_t *, int, int, char * const []);
 extern command_ret_t do_loadihex(cmd_tbl_t *, int, int, char * const []);
 #if defined(CONFIG_CMD_LOADB)
@@ -156,6 +157,27 @@ CMD_TBL_ITEM(
        "load srec_cat prepared image from controller flash",
        ""
 ),
+CMD_TBL_ITEM(
+       bootcf, CONFIG_SYS_MAXARGS,     0,      do_bootcf,
+       "boot from cf card",
+       "[options]\n"
+       "    Load a number of sectors from the first CP/M partition and jump to\n"
+       "    the load address.\n"
+       "    -a ADDRESS\n"
+       "            Load and start address (default 100 hex)\n"
+       "    -s NUM\n"
+       "            First sector of partition to load (0..255, default 0)\n"
+       "    -c NUM\n"
+       "            Number of sectors to load (1..127, default 7)\n"
+       "    -i NUM\n"
+       "            Partition type to look for (default 52 hex)\n"
+       "    -n\n"
+       "            Load only, do not execute\n"
+       "    -t NUM\n"
+       "            Timeout for IDE commands (1..65535, default 10000)\n"
+       "    -v verbose\n"
+       "            TODO: be verbose"
+),
 CMD_TBL_ITEM(
        loadcpm3, 3,    0,      do_loadcpm3,
        "load CPM3.SYS file",
@@ -364,7 +386,7 @@ CMD_TBL_ITEM(
        detach, 2,      1,      do_attach,
        "detach file from CP/M drive",
        "dsk<n>]\n"
-       "    - same as attach -d dsk<n>"
+       "    - alias for 'attach -d dsk<n>'"
 ),
 
 CMD_TBL_ITEM(
index c6727b9ba9187420eb51428d866863da4e56b207..159371f5261304964a26b0ca885b5063f041aaca 100644 (file)
@@ -89,7 +89,7 @@ hdrom.hex : $(OBJ)
        @#$(cpm-link)
        ld80 -o $@ -ms $(@:.hex=.map) -P $(LN_PROG) -D $(LN_DATA) $^
 
-%.rel %lst: %.180
+%.rel %.lst: %.180
        @$(cpm-asm)
 
 hdrom.map: hdrom.hex
index 50ede98bcb6289c9eed642a4d17e1aef1aa54db3..c7d79fbea81cfee4c8aef548fc4ebffd1d9fe6ca 100644 (file)
@@ -1,6 +1,7 @@
 include_rules
 
 PROG   = hdrom
+CFBOOT = cfboot
 
 SRC    = init.180
 SRC    += ddtz.180
@@ -48,6 +49,9 @@ rm -f ${OUTPUT}; exit ${ERROR} \
 : $(PROG).hex |> srec_cat -o %o -c_array %B -C_COMpressed -include %f -Intel |> $(PROG).c | $(PROG).h
 
 
+: $(CFBOOT).180 |> $(AS) -%B/HFS |> %B.hex | %B.lst
+: $(CFBOOT).hex |> srec_cat -o %o -c_array %B -C_COMpressed -include %f -Intel |> $(CFBOOT).c | $(CFBOOT).h
+
 #COMMAND="$(AS) -%B/$(AS_OPT)"; \
 
 
diff --git a/z180/cfboot.180 b/z180/cfboot.180
new file mode 100644 (file)
index 0000000..d8c39fd
--- /dev/null
@@ -0,0 +1,351 @@
+       TITLE 'CF cold boot loader'\r
+\r
+    ; Port Address Equates\r
+\r
+       include config.inc\r
+       include z180reg.inc\r
+\r
+    ; IDE Task File Register Definitions\r
+\r
+IDEDat equ     IDEBASE+0       ; Data Register\r
+IDEErr equ     IDEBASE+1       ; Error Register\r
+IDEFeat        equ     IDEBASE+1       ; Feature Register\r
+IDESCnt        equ     IDEBASE+2       ; Sector Count\r
+IDESNum        equ     IDEBASE+3       ; Sector Number\r
+IDECLo equ     IDEBASE+4       ; Cylinder Low\r
+IDECHi equ     IDEBASE+5       ; Cylinder High\r
+IDESDH equ     IDEBASE+6       ; Drive and Head\r
+IDECmd equ     IDEBASE+7       ; Command / Status\r
+\r
+    ; IDE Hard disk commands:\r
+\r
+CmdNOP equ     00h             ; NOP Command\r
+CmdHome        equ     10h             ; Recalibrate\r
+CmdRd  equ     20h             ; Read Sector\r
+CmdWr  equ     30h             ; Write Sector\r
+CmdId  equ     0ECh            ; Read ID\r
+CmdSF  equ     0EFh            ; Set Feature\r
+\r
+    ; Partition Table Structures\r
+\r
+PTYPE  equ     4\r
+PSTART equ     8\r
+PSIZE  equ     12\r
+\r
+    ; Partition table id\r
+    ; (see http://www.win.tue.nl/~aeb/partitions/partition_types-1.html)\r
+\r
+PARTID1_FAT16  equ     00EH\r
+PARTID2_FAT16  equ     006H\r
+PARTID_CPM     equ     052H\r
+\r
+\r
+DEBUG          equ     false           ; not used\r
+DO_WAIT_NBSY   equ     false\r
+RUN_TPA                equ     false\r
+\r
+   if RUN_TPA\r
+base           equ     0100h\r
+   else\r
+base           equ     0\r
+   endif\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+       aseg\r
+\r
+       org     base\r
+\r
+       jr      start\r
+\r
+para:          equ     $\r
+loadaddr:      dw      base+100h\r
+sec_start:     db      0\r
+sec_cnt:       db      7\r
+part_id:       db      PARTID_CPM\r
+timeout:       dw      10000\r
+stop_stage:    db      number_of_stages\r
+done:          db      0\r
+result:                db      0\r
+ide_result:    db      0,0\r
+\r
+o_part_id      equ     part_id      - para\r
+o_stop_stage   equ     stop_stage   - para\r
+o_done         equ     done         - para\r
+o_result       equ     result       - para\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+start:\r
+       ld      sp,stack\r
+       pop     ix\r
+       pop     de\r
+loop:\r
+       pop     hl\r
+       push    de\r
+       push    hl\r
+       exx\r
+       ld      hl,(loadaddr)\r
+       ret\r
+continue:\r
+       exx\r
+       ld      (ix+o_result),a\r
+       or      a\r
+       jr      nz,stop\r
+       dec     (ix+o_stop_stage)\r
+       jr      nz,loop\r
+stop:\r
+       in      a,(Idecmd)      ;2\r
+       ld      l,a             ;1\r
+       in      a,(IdeErr)      ;2\r
+       ld      h,a             ;1\r
+       ld      (ide_result),hl ;3      9\r
+       dec     (ix+o_done)\r
+       halt\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+chk_to:\r
+       xor     a       ;\r
+to_l:\r
+       dec     a\r
+       ex      (sp),hl\r
+       ex      (sp),hl\r
+       jr      nz,to_l ;\r
+       dec     hl      ; 4\r
+       ld      a,h     ; 4\r
+       or      l       ; 4\r
+       ret     nz      ; 10/5\r
+       ccf             ; 3\r
+       ret             ; 9\r
+\r
+   if base = 0\r
+     if 044h-$ > 0\r
+       rept    044h-$\r
+       db      0\r
+       endm\r
+     endif\r
+   endif\r
+\r
+part_start:\r
+;      dw      0\r
+;      dw      0       ; part_start is 4 byte long, but stack gets free\r
+stack:\r
+       dw      para\r
+       dw      continue\r
+stages:\r
+   if  DO_WAIT_NBSY\r
+       dw      s_wait_not_bsy\r
+   endif\r
+       dw      s_wait_rdy\r
+       dw      s_check_io\r
+       dw      s_set_xfermode8\r
+       dw      s_read_parttbl\r
+       dw      s_check_signature\r
+       dw      s_find_partition\r
+       dw      s_read_sectors\r
+       dw      s_go\r
+number_of_stages equ ($-stages)/2\r
+\r
+   if  DO_WAIT_NBSY\r
+;-------------------------------------------------------------------------------\r
+; Wait while device is busy with time out\r
+;     return:\r
+;       a = 0 if ok\r
+;       a = ff in timeout\r
+;     destroys hl\r
+\r
+s_wait_not_bsy:\r
+       ld      hl,(timeout)\r
+wnb_l:\r
+       in      a,(IdeCmd)\r
+       rla\r
+       jr      nc,wnb_e\r
+       call    chk_to\r
+       jr      nc,wnb_l\r
+wnb_e:\r
+       sbc     a,a\r
+       ret\r
+   endif\r
+\r
+;-------------------------------------------------------------------------------\r
+; Wait for ready signal with time out\r
+;     return:\r
+;       a = 0 if ok\r
+;       a = ff in timeout\r
+;     destroys hl\r
+\r
+s_wait_rdy:\r
+wait_rdy_to:\r
+       ld      hl,(timeout)\r
+wrdy_l:\r
+       in      a,(IdeCmd)\r
+       xor     01000000b\r
+       and     11000000b       ; clears carry\r
+       jr      z,wrdy_e\r
+       call    chk_to\r
+       jr      nc,wrdy_l\r
+wrdy_e:\r
+       sbc     a,a\r
+       ret\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+s_check_io:\r
+       ld      a,0E0h          ; unit 0, lba mode\r
+       out     (IdeSDH),a      ;\r
+\r
+       xor     a               ; execute NOP command\r
+       call    do_ide_cmd      ; should return error\r
+       ret     c\r
+       xor     1\r
+       ret     nz\r
+       ld      a,CmdHome       ; execute RECALIBRATE command\r
+       jr      do_ide_cmd\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+s_set_xfermode8:\r
+       ld      a,1             ; Enable 8-bit data transfer.\r
+       out     (IDEFeat),a\r
+       ld      a,CmdSF         ; Set feature command\r
+\r
+;      fall thru\r
+;      jr      do_ide_cmd\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+do_ide_cmd:\r
+       out     (IdeCmd),a      ;\r
+       call    wait_rdy_to\r
+       ret     c\r
+       in      a,(IdeCmd)\r
+       and     10001001b       ;\r
+       ret\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+s_check_signature:\r
+;      ld      hl,(loadaddr)\r
+       inc     h               ; Point to last byte of MBR\r
+       inc     h\r
+       dec     hl\r
+       ld      a,0aah\r
+       cp      (hl)                    ; Test, if it has a valid MBR\r
+       ret     nz\r
+       dec     hl\r
+       cpl                             ; a=055h\r
+       sub     (hl)                    ;\r
+       ret                             ; should be 0\r
+\r
+;-------------------------------------------------------------------------------\r
+; Read partition table (lbr)\r
+\r
+s_read_parttbl:\r
+;      ld      hl,(loadaddr)\r
+       ld      bc,1*256 + 0    ; sector 0 (lba)\r
+       ld      e,c\r
+       ld      d,c\r
+       jr      read_sectors\r
+\r
+;-------------------------------------------------------------------------------\r
+; Find CP/M paartition\r
+;      Look for first CP/M partition\r
+;      and save partition offset\r
+\r
+s_find_partition:\r
+;      ld      hl,(loadaddr)\r
+       ld      de,512-2-64+PTYPE       ; Point to  partition type of first first partition table entry\r
+       add     hl,de\r
+       ld      de,16\r
+       ld      b,4                     ; Max # of partition table entries\r
+ploop:\r
+       ld      a,(ix+o_part_id)\r
+       sub     (HL)                    ; Test for CP/M Partition\r
+       jr      nz,pnext\r
+       ld      bc,4\r
+       add     hl,bc                   ; Point to partition start (lba)\r
+       ld      de,part_start\r
+       ldir\r
+       ret                             ;a=0\r
+pnext:\r
+       add     hl,de\r
+       djnz    ploop\r
+       ret\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+; Read sec_count sectors, beginning at part_start+sec_start\r
+\r
+s_read_sectors:\r
+;      ld      hl,(loadaddr)\r
+       push    hl\r
+       ld      bc,(sec_start)          ;b=sec_count, c=sec_start\r
+       ld      e,c\r
+       ld      d,0\r
+       ld      hl,(part_start)         ;add partition offset to sector number\r
+       add     hl,de\r
+       ld      a,(part_start+2)\r
+       adc     a,d                     ;d=0\r
+       ld      c,a\r
+       ex      de,hl\r
+       pop     hl\r
+\r
+;      fall thru\r
+\r
+;-------------------------------------------------------------------------------\r
+; Read a number of sectors\r
+;      hl:  memory address\r
+;      cde: sector number (24 bit)\r
+;      b:   sector count\r
+\r
+read_sectors:\r
+       ld      a,e             ; lba 0..7\r
+       out     (IdeSNum),a\r
+       ld      a,d             ; lba 0..7\r
+       out     (IdeClo),a\r
+       ld      a,c             ; lba 0..7\r
+       out     (IdeCHi),a\r
+       ld      a,b             ; number of sectors to read\r
+       out     (IdeSCnt),a     ; set sector count\r
+\r
+       ld      a,CmdRd\r
+       out     (IdeCmd),a      ; command: read sector data\r
+       ld      d,b\r
+       ld      bc,IdeDat       ; I/O address\r
+wdrq:\r
+       in      a,(IdeCmd)      ; wait for DRQ to become active\r
+       bit     3,a\r
+       jr      z,wdrq\r
+       inir                    ; read 512 data bytes (2 x 256)\r
+       inir\r
+wnb:                           ; wait while busy\r
+       in      a,(IdeCmd)      ;\r
+       rlca\r
+       jr      c,wnb\r
+       rrca                    ; restore status\r
+       bit     0,a\r
+       jr      nz,err_out\r
+       dec     d\r
+       jr      nz,wdrq\r
+err_out:\r
+       and     10001001b       ; Busy, DRQ, or Error?\r
+       ret                     ; return 0, if everything is ok\r
+\r
+;-------------------------------------------------------------------------------\r
+\r
+s_go:\r
+;      ld      hl,(loadaddr)\r
+       dec     (ix+o_done)\r
+       jp      (hl)\r
+\r
+\r
+;-------------------------------------------------------------------------------\r
+   if base = 0\r
+     if $ > 100h\r
+       .printx Error: Program to large to fit in page 0!\r
+       db "Stop\r
+     endif\r
+   endif\r
+\r
+       end\r
index 4421478fec378303972501fa13e56ec1b3c10299..bea6e05cd302ac06d0121ae98c256d77570e4109 100644 (file)
@@ -3,8 +3,6 @@ FALSE   equ     0
 TRUE   equ     NOT FALSE\r
 \r
 \r
-DEBUG  equ     true\r
-\r
 banked equ     true\r
 \r
 ;-----------------------------------------------------\r
@@ -159,6 +157,8 @@ AVRINT5             equ     4Fh
 AVRINT6                equ     5Fh\r
 ;PMSG          equ     80h\r
 \r
+IDEBASE                equ     60h\r
+\r
 ;-----------------------------------------------------\r
 ; Definition of (logical) top 2 memory pages\r
 \r