mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-16 11:30:55 +00:00
riven_hgr: work on bootloader
This commit is contained in:
parent
b19ac206b7
commit
47b48f51b3
@ -382,7 +382,7 @@ submit: riven_disk00.dsk riven_disk01.dsk \
|
||||
|
||||
riven_hgr.2mg: PROBOOTHD disk01_files/LEVEL_ARRIVAL
|
||||
$(PRODOSDIR)/mkprodosfs riven_hgr.2mg -n Riven -b 65535 -2
|
||||
$(PRODOS_RAW) riven_hgr.2mg 0 0 PROBOOTHD
|
||||
$(PRODOS_RAW) riven_hgr.2mg 0 PROBOOTHD 0 0
|
||||
|
||||
###
|
||||
|
||||
|
267
games/riven_hgr/proboothd.s
Normal file
267
games/riven_hgr/proboothd.s
Normal file
@ -0,0 +1,267 @@
|
||||
;license:BSD-3-Clause
|
||||
|
||||
; based on minimal open/read binary file in ProDOS filesystem
|
||||
; from 4cade
|
||||
;
|
||||
;copyright (c) Peter Ferrie 2016-2019
|
||||
|
||||
.include "hardware.inc"
|
||||
|
||||
PROBOOTENTRY = $2000
|
||||
|
||||
; zpage usage, arbitrary selection except for the "ProDOS constant" ones
|
||||
command = $42 ; ProDOS constant
|
||||
UNIT = $43 ; ProDOS constant
|
||||
ADRLO = $44 ; ProDOS constant
|
||||
ADRHI = $45 ; ProDOS constant
|
||||
BLOKLO = $46 ; ProDOS constant
|
||||
BLOKHI = $47 ; ProDOS constant
|
||||
|
||||
A2L = $3e
|
||||
A2H = $3f
|
||||
sizehi = $53
|
||||
|
||||
|
||||
SCRN2P2 = $f87b ; shifts top nibble to bottom
|
||||
|
||||
dirbuf = $1e00 ;for size-optimisation
|
||||
|
||||
; start of boot sector, presumably how many sectors to load
|
||||
; 512 bytes on prodos/hard-disk(???)
|
||||
|
||||
.byte 1
|
||||
|
||||
proboot_start:
|
||||
txa
|
||||
pha ; save slot for later
|
||||
|
||||
; init. is all this necessary?
|
||||
; originally "4cade.init.machine.a"
|
||||
|
||||
cld ; clear direction flag
|
||||
sta $C082 ; read rom / no write (language card)
|
||||
sta PRIMARYCHARSET ; turn off mouse text
|
||||
sta EIGHTYCOLOFF ; disable 80-col mode
|
||||
sta CLR80COL
|
||||
sta READMAINMEM ; make sure not using aux mem
|
||||
sta WRITEMAINMEM
|
||||
sta SETSTDZP
|
||||
|
||||
; more init
|
||||
; originally "4cade.init.screen.a"
|
||||
|
||||
; initializes and clears screen using ROM routines
|
||||
|
||||
jsr INIT_TEXT ; setup text mode
|
||||
jsr HOME ; clear screen
|
||||
jsr SETNORM ; normal text
|
||||
jsr SETKBD ; keyboard input
|
||||
jsr SETVID ; video output
|
||||
|
||||
; set up disk stuff?
|
||||
|
||||
pla ; restore slot
|
||||
sta UNIT ; save for later
|
||||
|
||||
tax
|
||||
; X = boot slot x16
|
||||
|
||||
; Y = 0
|
||||
; 4cade calls a print-title routine here that exits with Y=0
|
||||
|
||||
ldy #0
|
||||
|
||||
; set up ProDOS shim
|
||||
|
||||
; from IIgs smartport firmware manual
|
||||
|
||||
; prodos entry point is $CX00+($CXFF)
|
||||
; so if slot 7, $C700 + value in $C7ff (say, A) so $C70A
|
||||
; smartport entry point is $CX00+(CXFF)+3
|
||||
|
||||
|
||||
setup_loop:
|
||||
txa
|
||||
jsr SCRN2P2 ; shift top nibble of A to bottom
|
||||
and #7
|
||||
ora #$c0
|
||||
sta $be30, Y ; ????
|
||||
sta slot_smc+2
|
||||
sta entry_smc+2 ; set up smartport/prodos entry point
|
||||
|
||||
slot_smc:
|
||||
lda $cfff
|
||||
sta entry_smc+1 ; set up rest of smartport/prodos entry
|
||||
|
||||
lda fakeMLI_e-$100, Y
|
||||
sta $be00+fakeMLI_e-fakeMLI, Y
|
||||
iny
|
||||
bne setup_loop ; ?????
|
||||
|
||||
; Y is 0 here
|
||||
; ldy #0
|
||||
sty ADRLO
|
||||
stx $bf30 ; ?????
|
||||
sty $200 ; ?????
|
||||
|
||||
opendir:
|
||||
; read volume directory key block
|
||||
ldx #2
|
||||
|
||||
; include volume directory header in count
|
||||
|
||||
firstent:
|
||||
lda #>dirbuf ; load volume block to ADDRH/L (dirbuf/$1e00)
|
||||
sta ADRHI
|
||||
sta A2H
|
||||
jsr seekread
|
||||
|
||||
|
||||
lda #4 ; start at filename offset
|
||||
sta A2L
|
||||
nextent:
|
||||
ldy #0
|
||||
|
||||
; match name lengths before attempting to match names
|
||||
; first byte, bottom nibble is length
|
||||
|
||||
lda (A2L), Y
|
||||
and #$0f
|
||||
tax
|
||||
inx
|
||||
|
||||
try_again:
|
||||
cmp filename, Y
|
||||
beq filename_char_match
|
||||
|
||||
; move to next directory in this block
|
||||
not_found:
|
||||
clc
|
||||
lda A2L
|
||||
adc #$27
|
||||
sta A2L
|
||||
bcc no_cross_page
|
||||
|
||||
; there can be only one page crossed,
|
||||
; so we can increment instead of adc
|
||||
|
||||
inc A2H
|
||||
no_cross_page:
|
||||
cmp #$ff ; 4+($27*$0d)
|
||||
bne nextent
|
||||
|
||||
; read next directory block when we reach the end of this block
|
||||
|
||||
ldx dirbuf+2
|
||||
ldy dirbuf+3
|
||||
bcs firstent
|
||||
|
||||
filename_char_match:
|
||||
iny ; point to next char
|
||||
lda (A2L), Y ; grab value
|
||||
dex ; countdown filename length
|
||||
bne try_again ; if not full match, keep going
|
||||
|
||||
|
||||
stx $ff ; set address $FF in zero page to zero?
|
||||
|
||||
; bytes $11 and $12 in the file entry are the "key pointer"
|
||||
|
||||
ldy #$11
|
||||
lda (A2L), Y
|
||||
tax
|
||||
iny
|
||||
lda (A2L), Y
|
||||
tay
|
||||
|
||||
|
||||
; seedling files = less than 512 bytes, contents are simply key block
|
||||
; storage type is $1
|
||||
; sapling files = 512B - 128k
|
||||
; key block has low bytes of addrss in 0..255 and high in 256..512
|
||||
; storage type is $2
|
||||
; tree files = 128k - 16M
|
||||
|
||||
|
||||
; read the 512-byte block at key pointer into memory
|
||||
; will only work for a "sapling" file?
|
||||
|
||||
readfile:
|
||||
jsr seekread
|
||||
|
||||
inc ADRHI ; point destination past it (so at $2000)
|
||||
inc ADRHI
|
||||
|
||||
; fetch contents of file?
|
||||
; just keep reading 512-byte blocks until done?
|
||||
; this means file will be at $2000?
|
||||
|
||||
blockind:
|
||||
ldy $ff ; use $ff as block index?
|
||||
inc $ff ;
|
||||
|
||||
ldx dirbuf, Y ; low byte of block#
|
||||
lda dirbuf+256, Y ; high byte of block#
|
||||
tay
|
||||
|
||||
bne readfile ; if high byte!=0, read another block
|
||||
|
||||
txa ; if high byte=0 and low_byte=0, done
|
||||
bne readfile
|
||||
|
||||
readdone:
|
||||
jmp PROBOOTENTRY ; would be $2000 if sapling
|
||||
|
||||
;================================
|
||||
; seek read
|
||||
;================================
|
||||
; Y:X = block number to load (???)
|
||||
; A = page to load to?
|
||||
|
||||
seekread:
|
||||
stx BLOKLO
|
||||
sty BLOKHI
|
||||
lda #1
|
||||
sta command
|
||||
lda ADRHI
|
||||
pha
|
||||
entry_smc:
|
||||
jsr $d1d1
|
||||
pla
|
||||
sta ADRHI
|
||||
rts
|
||||
|
||||
fakeMLI:
|
||||
bne retcall
|
||||
readblk:
|
||||
dey
|
||||
dey
|
||||
sty ADRHI
|
||||
tay
|
||||
jsr $bf00+seekread-fakeMLI
|
||||
retcall:
|
||||
pla
|
||||
tax
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
txa
|
||||
pha
|
||||
;-:
|
||||
rts
|
||||
fakeMLI_e:
|
||||
|
||||
|
||||
filename:
|
||||
; expects PASCAL-string filename
|
||||
; first byte size (max 15)
|
||||
.byte 7,"SEASONS"
|
||||
|
||||
;.if (* > $9f7)
|
||||
; .error "Bootloader is too large"
|
||||
;.endif
|
||||
|
||||
;*=$9f8
|
||||
;!byte $D3,$C1,$CE,$A0,$C9,$CE,$C3,$AE
|
||||
; S A N I N C .
|
||||
;
|
146
utils/prodos-utils/prodos_raw.c
Normal file
146
utils/prodos-utils/prodos_raw.c
Normal file
@ -0,0 +1,146 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* usage: dos33_raw track sector file */
|
||||
static void usage(char *exe_name) {
|
||||
printf("Usage:\n");
|
||||
printf("\t%s disk_image track sector file start count [max_track]\n\n",exe_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int dos33_sector_map[16]={
|
||||
0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15
|
||||
};
|
||||
|
||||
static int goto_dos_track_sector(int fd, int track, int sector) {
|
||||
|
||||
int result,translated_sector;
|
||||
|
||||
translated_sector=dos33_sector_map[sector%16];
|
||||
|
||||
result=lseek(fd,(translated_sector*256)+(track*16*256),SEEK_SET);
|
||||
|
||||
// printf("going to: T=%d S=%d (%d)\n",track,sector,translated_sector);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
unsigned int track,sector,start,count,total,max_track,filesize;
|
||||
unsigned int max_sector,check_max=0;
|
||||
int disk_image_fd;
|
||||
int file_fd;
|
||||
unsigned char buffer[256];
|
||||
int result,read_result;
|
||||
struct stat statbuf;
|
||||
|
||||
if (argc<7) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
track=atoi(argv[2]);
|
||||
sector=atoi(argv[3]);
|
||||
start=atoi(argv[5]);
|
||||
count=atoi(argv[6]);
|
||||
|
||||
if (argc>7) {
|
||||
max_track=atoi(argv[7]);
|
||||
check_max=1;
|
||||
}
|
||||
|
||||
/* check filesize using stat */
|
||||
result=stat(argv[4], &statbuf);
|
||||
if (result<0) {
|
||||
fprintf(stderr,"Error stating %s: %s\n",
|
||||
argv[4],strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
filesize=statbuf.st_size;
|
||||
|
||||
if (count==0) {
|
||||
count=(filesize/256);
|
||||
if ((filesize%256)!=0) count++;
|
||||
}
|
||||
|
||||
/* sanity check we aren't going off the last track */
|
||||
if (check_max) {
|
||||
max_sector=((track*16)+sector+count);
|
||||
if (max_sector >= max_track*16) {
|
||||
fprintf(stderr,"Error, %d exceeds max_sector of %d\n",
|
||||
max_sector,max_track*16);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (track>34) {
|
||||
fprintf(stderr,"Warning! Unusual track number %d\n",track);
|
||||
}
|
||||
|
||||
if (sector>15) {
|
||||
fprintf(stderr,"Warning! Unusual sector number %d\n",sector);
|
||||
}
|
||||
|
||||
disk_image_fd=open(argv[1],O_RDWR);
|
||||
if (disk_image_fd<0) {
|
||||
fprintf(stderr,"Error opening %s: %s\n",
|
||||
argv[1],strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file_fd=open(argv[4],O_RDONLY);
|
||||
if (file_fd<0) {
|
||||
fprintf(stderr,"Error opening %s: %s\n",
|
||||
argv[4],strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result=lseek(file_fd,(start*256),SEEK_SET);
|
||||
if (result<0) {
|
||||
fprintf(stderr,"Error skipping: %s\n",strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
total=0;
|
||||
/* write until out of space */
|
||||
while(1) {
|
||||
if (total>=count) break;
|
||||
|
||||
read_result=read(file_fd,buffer,256);
|
||||
if (read_result<0) break; /* error */
|
||||
if (read_result==0) break; /* done */
|
||||
|
||||
result=goto_dos_track_sector(disk_image_fd,track,sector);
|
||||
if (result<0) {
|
||||
fprintf(stderr,"Error seeking: %s\n",strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
result=write(disk_image_fd,buffer,read_result);
|
||||
if (result<0) {
|
||||
fprintf(stderr,"Error writing image: %s\n",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
total++;
|
||||
sector++;
|
||||
if (sector==16) {
|
||||
sector=0;
|
||||
track++;
|
||||
}
|
||||
}
|
||||
|
||||
close(file_fd);
|
||||
close(disk_image_fd);
|
||||
|
||||
fprintf(stderr,"Wrote %d sectors\n",count);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user