Author Topic: Reading data directly from archive  (Read 3107 times)

0 Members and 1 Guest are viewing this topic.

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Reading data directly from archive
« on: October 16, 2012, 01:46:07 pm »
Alright, so i wrote a little piece of code to swap the ROM page of the level file in and locate the first bits of data and it seems to be working perfectly. However, i am pretty sure this is only because on the emulator my FLASH is pretty much empty and it's getting loaded into the low values of $4000. Am i right in assuming that this is just "luck" and that on a regular calculator where the archive is fuller that it's possible the data file (well over 8k) will span two pages?

This is the code that i wrote, it finds the file in archive, swaps it in, and reads maplocations from a map table at the start of the data file:
Code: [Select]
loadLevelFromArchive:
push bc
ld hl,levelName_txt
rst 20h ;9 octets à (hl) dans OP1
bcall(_ChkFindSym) ;chercher le programme dans OP1
;hl = VAT, de = addresse du data
ret c ;c armé si pas encontré
in a,(6) ;il faut sauvegarder la page FLASH actuelle
ld (savePort),a
ld a,b ;b = 0 si le fichier est dans RAM
or a
ret z ;si pas dans le RAM, b = la page FLASH
out (6),a ;a = la page FLASH où est notre fichier
ex de, hl
ld de,20-6 ;-6 parce que b=1 est la première carte, on va ajouter 6
add hl,de ;il y a 20 octets avant le début du data, le nom du program, sa taille, addresse, page de FLASH, etc.
pop bc
;début du data
ld e,6
add hl,de
djnz $-1
; Aller prendre les informations dans les infos et mettre dans hl, de bc avant de lancer chargerCarte

;...do stuff

savePort = $+1
ld a,0
out (6),a
ret
What can i do to handle cases where it spans more than one page? I can check to see if hl passes $7FFF, but how do i know what the next page is?
« Last Edit: October 16, 2012, 01:47:27 pm by chickendude »

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Reading data directly from archive
« Reply #1 on: October 16, 2012, 05:36:09 pm »
The next page is simply the next page. Literally. So if you run off of 08, the next page is 09. You never have to worry about it crossing a sector (i.e. 0B -> 0C or 0F -> 10) because TI's file structure doesn't allow it.

One problem I immediately see with your code is that it assumes that the name of the program is going to be exactly 4 letters long, if that's true, then cool, but otherwise you'll have to add some code to fix that.

Here is a relevant wikiTI article on the flash variable format, what you're interested in starts at "After the status byte for that sector..."


Anyways, the best way to check if you went over $7FFF is to check bit 7 of h. If bit 7 is set, then increase the page number by one, reset bit 7, and set bit 6.

Here is how I've been doing this whole process for the past 3 years: (this is from zStart)
Code: [Select]

ld hl, name
rst 20h
bcall(_chkFindSym)
call findStartInRom

...

;##################################
;Move to start of data in Rom
;Input: Output of _ChkFindSym
;Output: HL = start
; B = rom page
;Destroys: C DE


FindStartInRom:
ex de, hl

LD de, 9

add hl, de

call fast_bhl

bcall(_LoadCIndPaged)     ; number of letters in variable name

inc c
ld e, c

add hl, de
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;fall through
;########################################
;faster bhl
;only checks for going over

fast_bhl:
ld a, h
res 7, h
set 6, h      ; this is a little hacky to save space, but it does what I said it does
cp h
ret z
inc b
ret


Also, if speed isn't an issue, there's always bcall(_flashToRam) (it's not actually all that slow).
« Last Edit: October 16, 2012, 05:36:33 pm by thepenguin77 »
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: Reading data directly from archive
« Reply #2 on: October 16, 2012, 06:43:11 pm »
Also, if you really like speed, you can use this method for adding or incrementing in flash:
Code: [Select]
  ; Increase flash pointer
  inc l
  call z,inc_flash_high

  ;...

  ; Add to flash pointer
  ld a,OFFSET
  add a,l
  ld l,a
  call c,inc_flash_high
 
  ;...

inc_flash_high:
  inc h
  ret po
  ld h,$40
  in a,(6)
  inc a
  out (6),a
  ret

Edit: Just realized that res 7,h \ set 6,h is too much code for this particular routine since H only increases by 1 each time.

Edit2: Okay yeah B is irrelevant, just increases the mapped flash page now :P
« Last Edit: October 17, 2012, 08:24:41 am by calc84maniac »
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: Reading data directly from archive
« Reply #3 on: October 16, 2012, 06:46:31 pm »
Awesome, thanks! And when you say "crossing a sector", i don't understand the difference between a "page" and a "sector". Is a page swapped into a sector? And the filename will always be the same since there's only going to be one file. The program is getting too large to fit the level packs in so i wanted to try making them external. Speed's not an issue and i would've used _FlashToRam, but the thing is the levels are RLE compressed and i wanted to unpack them directly into my buffer (rather than look for ANOTHER 2k+ space in RAM to store the compressed levels into).

Another option might be to calculate how many bytes are left until i reach the next page and load it into bc or something and switch to the next page when the counter runs down (or just exit if i reach the end of data before the page ends), that way i don't have to test after every byte read. I like that "fast_bhl" routine, it's pretty clever :)

EDIT: Alright, it's finally working like a charm :D My 83+ arrived today and the first thing i did was toss my program on there and much to my dismay many of the levels were crashing. I added these few lines in (which i think is slightly shorter/faster than the code above? If it is, to you or anyone else: "help yourself!"):
Code: [Select]
ld a,%10000000
and h
jr z,continueRLE
rra
ld h,a
in a,(6) ;charger la prochaine page de FLASH
inc a
out (6),a
continueRLE:
...and now it's working great. Thanks a lot :)

EDIT2: Not faster than calc84maniac's code ;) I just saw your post, thanks :)

EDIT3: Errr... maybe not. It works fine now on the emulator but oncalc it's buggy :/

EDIT4: (sorry) And i just ran it again and now it's working perfectly. It's so weird. I can't remember if i garbage collected or not, i think so, which might be why it's working now :/

EDIT5 (and final!): I finally figured out what was causing it, my routine works fine once you have the address and are advancing one by one, but to get the initial offset you need to use one of the other routines since they don't depend on you changing hl one byte at a time. Now everything's working great on both the emulator and hardware :D
« Last Edit: October 17, 2012, 08:58:57 am by chickendude »

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Reading data directly from archive
« Reply #4 on: October 23, 2012, 01:20:25 pm »
Edit5 was exactly what I was going to point out about your routine. But I'm glad you got it working.

Btw, for an update like this, you can totally double post. I do it all the time.
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Reading data directly from archive
« Reply #5 on: October 24, 2012, 04:07:40 pm »
This isn't very on-topic, but if besides reading data from archive you also plan to write to it, be very careful to not mess up and writing to the wrong Flash sector (OS certificate). This can permanently damage your calc. Not sure if reading the archive directly from the wrong sector can cause damage, though.

Offline thepenguin77

  • z80 Assembly Master
  • LV10 31337 u53r (Next: 2000)
  • **********
  • Posts: 1594
  • Rating: +823/-5
  • The game in my avatar is bit.ly/p0zPWu
    • View Profile
Re: Reading data directly from archive
« Reply #6 on: October 25, 2012, 06:43:26 pm »
This isn't very on-topic, but if besides reading data from archive you also plan to write to it, be very careful to not mess up and writing to the wrong Flash sector (OS certificate). This can permanently damage your calc. Not sure if reading the archive directly from the wrong sector can cause damage, though.

Reading from flash and writing to flash are very very different. Reading is super simple and the flash just acts like ram. Flash is constantly being read when the calculator is turned on and the OS functions by simply running from flash. In order to actually write to flash, you have to first unlock flash and then use some very specific bcalls to write data. On top of that, to mess with the certificate, you have to accidentally write to page 7Eh which if you are going to randomly write to a page, is only a 1/256 chance. (I said "flash" way to many times, but I don't think I can avoid that)

So yes, thanks for the warning, but no, that can't possible happen.
zStart v1.3.013 9-20-2013 
All of my utilities
TI-Connect Help
You can build a statue out of either 1'x1' blocks or 12'x12' blocks. The 1'x1' blocks will take a lot longer, but the final product is worth it.
       -Runer112