fname "SAVEROM.COM" ; SaveROM.mac, tniASM version org 100h start: ld de,IntroMsg ld c,9 call 5 ld a,(5dh) cp ' ' jr z,ShowUsage ld a,(6dh) cp ' ' jr nz,ShowUsage call CheckMem call input ld de,SavingMsg ld c,9 call 5 call CreateFile call SaveFile call CloseFile ld de,SaveOK ld c,9 call 5 rst 0 ShowUsage: ld de,usage ld c,9 call 5 rst 0 input: ld de,PrimMsg ld hl,Prim call do_inp ld hl,(prim) ld a,h or a jr nz,input ld a,l cp 4 jr nc,input ld (slot),a ld bc,0fcc1h add hl,bc ld a,(hl) or a jp p,no_sec input2: ld de,SecMsg ld hl,Sec call do_inp ld hl,(Sec) ld a,h or a jr nz,input2 ld a,l cp 4 jr nc,input2 sla a sla a or 80h ld hl,slot or (hl) ld (hl),a no_sec: ld de,MegaMsg ld c,9 call 5 euh: ld c,8 call 5 ld c,1 cp 'y' jr z,okay cp 'Y' jr z,okay dec c cp 'n' jr z,okay cp 'N' jr nz,euh okay: push bc ld de,Output ld (de),a ld c,9 call 5 pop bc ld a,c ld (type),a or a jp z,normal ; assume megarom ld de,SwAdMsg ld hl,swaddr call do_inp ld de,SaAdMsg ld hl,saaddr call do_inp ld de,BlSizeMsg ld hl,bloksize call do_inp ToHighFB: ld de,FirstMsg ld hl,firstblok call do_inp ld a,(firstblok+1) or a jr nz,ToHighFB ToHighLB: ld de,LastMsg ld hl,lastblok call do_inp ld a,(lastblok+1) or a ret z jr ToHighLB do_inp: ld (string),de ld (des),hl ld de,(string) ld c,9 call 5 ld hl,InputStr ld b,4 NumbWrong: push bc push hl ld c,8 call 5 pop hl pop bc cp 13 jr z,return cp 8 jp z,bs cp 7fh jp z,bs ld c,a ld a,b or a jr z,NumbWrong ld a,c sub '0' jr c,NumbWrong cp 10 jr c,NumbOk ld a,c cp 'f'+1 jr nc,NumbWrong and NOT 32 cp 'F'+1 jr nc,NumbWrong sub 'A' jr c,NumbWrong add a,10 NumbOk: ; echo push af push bc push hl ld e,c ld c,2 call 5 pop hl pop bc pop af ; store it ld (hl),a inc hl dec b jr NumbWrong return: ld a,b cp 4 jr z,NumbWrong push bc push hl ld de,crlf ld c,9 call 5 pop hl pop bc ; do some parsing stuff ld hl,InputStr ld de,0 NextNumb: ld c,(hl) ld a,b cp 4 jr z,NumbComplete inc b inc hl sla e rl d sla e rl d sla e rl d sla e rl d ld a,e or c ld e,a jr NextNumb NumbComplete: ld hl,(des) ld (hl),e inc hl ld (hl),d ret bs: ld a,b cp 4 jp nc,NumbWrong push bc push hl ld c,2 ld e,127 call 5 pop hl pop bc dec hl inc b jp NumbWrong normal: ld de,BeginAdMsg ld hl,firstadd call do_inp ld de,EndAdMsg ld hl,lastadd jp do_inp CreateFile: ld bc,39 ld de,FCB+1 ld hl,FCB ldir ld hl,5ch ld de,FCB ld bc,12 ldir ld de,FCB ld c,16h call 5 or a jr z,CreateOK ld de,CreateErr ld c,9 call 5 rst 0 CreateOK: ld hl,1 ld (FCB+14),hl ld l,h ; clears HL ld (FCB+33),hl ld (FCB+35),hl ret FileSave: push af push bc push de push hl ld de,FCB ld c,26h call 5 or a jr nz,SaveError pop hl pop de pop bc pop af ret SaveError: ld de,SaveErr ld c,9 call 5 rst 0 CloseFile: ld de,FCB ld c,10h call 5 or a ret z ld de,SaveErr ld c,9 call 5 rst 0 CheckMem: ld hl,(6) ld a,h cp 0c0h ret nc ld de,MemoryErr ld c,9 call 5 rst 0 SaveFile: ld a,(type) or a jr z,SaveStdROM ; assume megarom ; we will use the routine for Standard ROMs for ; every blok. Iterates from (firstblok) to ; (lastblok). ld hl,(saaddr) ld (firstadd),hl ld de,(bloksize) add hl,de dec hl ld (lastadd),hl ; the actual loop ld a,(firstblok) ld e,a ld a,(lastblok) ld d,a cp e jr c,NextBlokI NextBlok: push de ld a,(slot) ld hl,(swaddr) call 14h call SaveStdROM pop de inc e ld a,d or a jr z,Till1 cp e jr nc,NextBlok ret Till1: ld a,e dec a jr nz,NextBlok ret NextBlokI: push de ld a,(slot) ld hl,(swaddr) call 14h call SaveStdROM pop de dec e ld a,d or a jr z,TillFF ld a,e cp d jr nc,NextBlokI ret TillFF: ld a,e inc a jr nz,NextBlokI ret ; this funtion saves memory area (firstadd - lastadd) in ; slot (slot) to disk SaveStdROM: ld hl,(firstadd) ld a,h cp 40h jr nc,SavePage1 call Page0Copy ld hl,(firstadd) ld de,8000h add hl,de ex de,hl ld c,1ah call 5 ld de,(firstadd) ld hl,(lastadd) ld a,h cp 040h jr c,NoOF0 ld hl,3fffh NoOF0: or a sbc hl,de inc hl call FileSave SavePage1: ld hl,(firstadd) ld a,h cp 080h jr nc,SavePage2 ld hl,(lastadd) ld a,h cp 040h ret c call Page1Copy ld hl,(firstadd) ld a,h cp 040h jr nc,NoOF10 ld hl,4000h NoOF10: ; set write address push hl ld de,4000h add hl,de ex de,hl ld c,1ah call 5 ; calc length ld hl,(lastadd) ld a,h cp 080h jr c,NoOF11 ld hl,7fffh NoOF11: pop de or a sbc hl,de inc hl call FileSave SavePage2: ld hl,(firstadd) ld a,h cp 0c0h jr nc,SavePage3 ld hl,(lastadd) ld a,h cp 080h ret c call Page2Copy ld hl,(firstadd) ld a,h cp 080h jr nc,NoOF20 ld hl,8000h NoOF20: ; set write address push hl ex de,hl ld c,1ah call 5 ; calc length ld hl,(lastadd) ld a,h cp 0c0h jr c,NoOF21 ld hl,0bfffh NoOF21: pop de or a sbc hl,de inc hl call FileSave SavePage3: ld hl,(lastadd) ld a,h cp 0c0h ret c call Page3Copy ld hl,(firstadd) ld a,h cp 0c0h jr nc,NoOF30 ld hl,0c000h NoOF30: ; set write address push hl ld de,4000h or a sbc hl,de ex de,hl ld c,1ah call 5 ; calc length ld hl,(lastadd) pop de or a sbc hl,de inc hl jp FileSave ; These functions copy memory pages 0, 1, 2 or 3 from ; (slot) to page 2 RAM. Used for saving them. Page0Copy: di ld a,(0f342h) ld h,40h call 024h ld a,(0f343h) ld h,80h call 024h ld hl,MoveIt ld de,4000h ld bc,100h ldir jp 4000h MoveIt: di ld a,(slot) bit 7,a jr nz,SubSlots and 3 ld c,a in a,(0a8h) ld (4100h),a and 0fch or c out (0a8h),a ld hl,0 ld de,8000h ld bc,4000h ldir ld a,(4100h) out (0a8h),a ei ret SubSlots: ld e,a ld a,(0ffffh) cpl ld c,a in a,(0a8h) ld b,a ld (4100h),bc ld a,e and 3 ld d,a rrca rrca or d ld d,a ld a,b and 03ch or d out (0a8h),a ld a,(0ffffh) cpl and 0fch ld d,a ld a,e rrca rrca and 3 or d ld (0ffffh),a ld hl,0 ld de,8000h ld bc,4000h ldir ld bc,(4100h) ld a,b out (0a8h),a ld a,c ld (0ffffh),a ei ret Page1Copy: di ld a,(slot) ld h,40h call 024h ld a,(0f343h) ld h,80h call 024h ld hl,4000h ld de,8000h ld bc,4000h ldir ld a,(0f342h) ld h,40h call 024h ei ret Page2Copy: di ld a,(slot) ld h,80h call 024h ld hl,8000h ld de,4000h ld bc,4000h ldir ld a,(0f343h) ld h,80h call 024h ld hl,4000h ld de,8000h ld bc,4000h ldir ei ret Page3Copy: di ld a,(0f343h) ld h,80h call 024h ld a,(slot) bit 7,a jr nz,SubSlots2 rrca rrca and 0c0h ld c,a in a,(0a8h) ld (temp),a and 03fh or c out (0a8h),a ld hl,0c000h ld de,08000h ld bc,04000h ldir ld a,(temp) out (0a8h),a ei ret SubSlots2: ld c,a rrca rrca and 0c0h ld b,a ld a,(0ffffh) cpl ld (temp+1),a in a,(0a8h) ld (temp),a and 03fh or b out (0a8h),a ld a,(0ffffh) cpl and 03fh ld b,a ld a,c rlca rlca rlca rlca and 0c0h or b ld (0ffffh),a ld hl,0c000h ld de,08000h ld bc,04000h ldir ld a,(temp) out (0a8h),a ld a,(temp+1) ld (0ffffh),a ei ret ; "temp" variables string: dw 0 des: dw 0 temp: dw 0 ; information about cartridge to save Prim: dw 0 Sec: dw 0 slot: db 0 type: db 0 swaddr: dw 0 saaddr: dw 0 bloksize: dw 0 firstblok: dw 0 lastblok: dw 0 firstadd: dw 0 lastadd: dw 0 ; strings Output: db 0 crlf: db 13,10,'$' IntroMsg: db 'SaveROM 1.1',13,10,'By Sean Young 1997, 1998, ' db 'BiFi 2007',13,10,10,'$' PrimMsg: db 'Primary Slot: $' SecMsg: db 'Secondary Slot: $' MegaMsg: db 'MegaROM (y/n)? $' SwAdMsg: db 'Switch Address: $' SaAdMsg: db 'Save Address: $' BlSizeMsg: db 'Block Size: $' FirstMsg: db 'First Block: $' LastMsg: db 'Last Block: $' BeginAdMsg: db 'Begin Address: $' EndAdMsg: db 'End Address: $' InputStr: db '0000',13,10 Usage: db 'Usage:',13,10,10 db ' saverom ',13,10,'$' SavingMsg: db 13,10,'Saving...',13,10,'$' CreateErr: db 'File creation error!',13,10,'$' MemoryErr: db 'Not enough memory!',13,10,'$' SaveErr: db 'Save error!',13,10,'$' SaveOK: db 'Save completed.',13,10,'$' FCB: db 0