Gönderen Konu: Spectrum'la ilgili bir soru.  (Okunma sayısı 434 defa)

0 Üye ve 3 Ziyaretçi konuyu incelemekte.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Spectrum'la ilgili bir soru.
« : 22 Nisan 2022, 11:13:45 »
Soru spectrumda bir basic satırının yapısıyla ilgili. Önce sorunun ortaya çıkış sebebini yazıyım.

C64'te bir basic programı 2049 ($0801) adresinden  başlar ve 2022 SYS adres şeklindeki bir satırın yapısı şu şekildedir.
$0801-$0802: Bir sonraki basic satırının başlangıç adresi. Gösterilen adresin içeriği $0000 ise programın sonu demektir.
$0803-$0804: Satır numarası
$0805: SYS komutunun kodu ($9e)
$0806....: programın çalışma adresinin ascii değerleri
Son olarak o program satırının sonunu gösteren $00 değeri.
Arka arkaya üç adet $00'dan sonra ise makine kodu/data bulunur. Yani tek satırlık bir komutun devamında asıl program/data bulunur.

Spectrumda da aynı şey yapılabilir mi diye uğraşmaya başladım ama dump ettiğimde tek satırlık bir programda bile fazladan baytlar gözüküyor. Dokümanlara göre bir Basic programının bitiminde hemen değişkenler başlıyor. Program satırının uzunluğu falan derken işler karışıyor.

"2022 RANDOMIZE USR ADRES" + kod şeklindeki bir programda adres en düşük ne olabilir?

 

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #1 : 22 Nisan 2022, 13:07:43 »
Efendim, madem bugün ZX Spectrum'un 40. yılı yüzü suyu hürmetine klavye başındayım (evet, sadece bugünlük! ;)), konunun uzmanı @Ref hocamızdan müsaade isteyerek sorunuzu yanıtlayayım.

... ama dump ettiğimde tek satırlık bir programda bile fazladan baytlar gözüküyor. Dokümanlara göre bir Basic programının bitiminde hemen değişkenler başlıyor. Program satırının uzunluğu falan derken işler karışıyor.

ZX Spectrum BASIC interpreter, her değişken için hafızada 2 değer saklar:

1.) LIST komutu ile ekrana basılacak "göstermelik" değer.
2.) Üzerinde hesap-kitap yapılacak "gerçek" değer.

Basit bir örnekle açıklayayım:

Kod: [Seç]
10 LET A=3
20 PRINT A

Bu kodu RUN komutuyla çalıştırdığımızda ekranda 3 sayısı belirir.

Kod: [Seç]
3
Şimdi, küçük bir hokus-pokus ile A değişkeninin "gerçek" değerini 255 yapalım.

Kod: [Seç]
POKE 23767,255
yazıp, ENTER'a basalım. Şimdi RUN komutunu çalıştırdığımızda ekranda 255 sayısı belirir.

Kod: [Seç]
255
İlginç olan, eğer LIST komutu ile kodu listelerseniz, ilk satırda hâlâ A=3 yazdığını görebilirsiniz. ;)

Kod: [Seç]
10 LET A=3
20 PRINT A

BASIC interpreter'ın token ve değişken yönetimi oldukça dinamik. &5C00-&5CB6 arasındaki sistem değişkenleri BASIC interpreter için pointer map görevi görüyor. Daha geniş bilgi için Dr. Ian Logan'ın kitaplarını tavsiye ederim. Zira, pek kapsamlı bir başlık bu...

"2022 RANDOMIZE USR ADRES" + kod şeklindeki bir programda adres en düşük ne olabilir?

Sanırım RANDOMIZE USR komutuyla çağırılan adresi kastediyorsunuz. İçeriği geçerli olduğu sürece, 16-bit adres olması yeterli.

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #2 : 22 Nisan 2022, 15:23:59 »
Soruyu doğru ifade edemedim. Adres değerinde bir sıkıntı yok.
Ekran görüntüsünde 2022 RANDOMIZE USR 23800 satırının bellekteki yerleşimine baktığımızda ilk olarak satır numarasının HI-LO formatında 07 E6 olarak görüyoruz. Ancak dump incelendiğinde 2022'nin bu kez tek tek ascii kod olarak saklandığı görülüyor. (Kırmızı çizgili)
Aynı şekilde RANDOMIZE ($F9) ve USR ($C0) değerleri 2022'nin ascii değerlerinden sonra tekrar yer alıyor. Çalışma adresi olan 23800 de aynı şekilde ascii olarak sıralanıyor.
Diğer yandan çalışma adresi 23800 LO-HI şeklinde $F85C olarak iki kez yer alıyor.
Dumpa göre bir randomize usr şeklindeki bir satırın devamında yer alacak bir kodun konuşlanacağı ve çalışacağı en düşük adres 23800 olarak gözüküyor. Aradaki bytları dikkate almadan çalışma adresi daha düşük olabilir mi biraz uğraşayım.
Satır uzunluğu ilk komuttan itibaren sayarak 14 byte, ki $0E komut satırının uzunluğu. Tek satırlık bir program hafızada daha çok yer kaplıyor.

Hem komutların hem de diğer sayısal değerlerin tekrarlanması kafamı karıştırdı.


Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #3 : 22 Nisan 2022, 16:13:56 »
@hades: Açıklayıcı yanıtınız için teşekkür ederim. Sorununuzu şimdi çok daha iyi anladım.

Sizin örneğinizi biraz geliştirelim:

Kod: [Seç]
2022 RANDOMIZE USR 23800
2023 REM MATAHARI
2024 REM HADES

Şimdi bu kodun hafızadaki yerleşimine bakalım:

 


Kolayca görüleceği üzere 2022 ve 2023 nolu satırlar gayet optimized biçimde konumlanmış, ancak son girilen 2024 nolu satır 2 kez tekrar edilmiş. Neden? Çünkü, "aktif olarak girmekte olduğunuz kod" (yani henüz enter'a basmadan önce sayfanın altındaki komut satırına tuşladığınız bölüm), mevcut BASIC kod bloğunun hemen ardına "buffer"lanıyor. Siz Enter'a bastığınız anda o satır interpret edilerek en son satır olarak kod bloğuna ekleniyor, ancak buffer olarak kullanılan alan temizlenmiyor. En sonda gördükleriniz, artık garbage olmuş data. 8)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #4 : 22 Nisan 2022, 17:02:52 »

Arka arkaya üç adet $00'dan sonra ise makine kodu/data bulunur. Yani tek satırlık bir komutun devamında asıl program/data bulunur.

Spectrumda da aynı şey yapılabilir mi diye uğraşmaya başladım ama dump ettiğimde tek satırlık bir programda bile fazladan baytlar gözüküyor. Dokümanlara göre bir Basic programının bitiminde hemen değişkenler başlıyor. Program satırının uzunluğu falan derken işler karışıyor.

"2022 RANDOMIZE USR ADRES" + kod şeklindeki bir programda adres en düşük ne olabilir?
Şimdi ben de anlamaya çalıştım soruyu, c64'den hiç anlamadığım için yaya kaldım. Amacın basic programı içinde çok yakına bir makine kodu sıkıştırmak mı acaba?

Eğer buysa, söylediğin şey mataharinin açıkladığı sebeple basic'in peşinde (LineBuffer orada duruyor) olmaz ama genelde REM satırına (ya da bir stringin içine) konuyor o durumda makine kodu.

örnek
Kod: [Seç]
10 REM XXXXXXXXXXX buraya relocatable ASM KODUNU DERLEYECEKSİN XXXXXXXX (~240byte lık data tutabilir, tam rakam ezberimde yok)
20 RANDOMIZE USR ((PEEK 23635+256*PEEK 23636)+5)
(basic'in konumu kullanıcının daha önce yaptığı işlemlere göre nadiren değişebildiği için onu sistem değişkeninden okumak daha garanti, 20.satırdaki PEEK'ler o yüzden var)


Fakat bir hatırlatma, basic'in bu ilk kısmı ilk 16K'lık ram'de bulunuyor. Bu bölge ekran kaşesi ile aynı çipte kalıyor. Bu sebepten ekran çizilirken Z80 o bölgeye ulaşmak için ara sıra beklemek zorunda kalacaktır. Yani eğer kodunuz 32768'den küçük bir adreste çalışıyorsa gecikmeye uğrayacaktır. Bu bölgede çalışan kodun değişik davranışları olacaktır. Contention konusunda uzmanlaşmadan burada time critical kod çalıştırmak çizimde rastlantısal sonuçlar almana sebep olabilir. Ayrıca yaklaşık %5 yavaş çalışacaktır.

Bu arada basic değişkenlerinin yerini değiştirmek mümkün, CLEAR komutu ile yapılabilir. fakat değişkenler zaten ram'in dibinde $FDE8 civarı tutuluyor.
CLEAR 24800 vb gibi birşey yaparsan değişkenler basic'e yaklaşır hatta birleştirebilirsin. Eğer birbirinin üzerine yazmaya başlarlarsa Ramtop no good hatası alırsın.



Ek olarak Basic'in ekrandaki temsili ile ilgili bir komik program paylaşıyorum, ters çalışan basic!
 


deneyin ve mucizeyi görün! :)

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #5 : 22 Nisan 2022, 17:37:32 »
@matahari açıklamalar için teşekkürler. Konuyu daha iyi anladım. Garbage baytlar kafa karıştırıyormuş.
@Ref evet tahmin ettiğin gibi. Basic dibine kod eklemek ve load"" code kullanmadan tüm kodu sadece load"" ile basic programıymış gibi yüklemek.

En düşük adres 23774 oluyor. Garbage datalar yüzünden evdeki bilgisayarda hatalı çalışan/çalışmayan kodu düzeltme zamanı geldi.

Kod: [Seç]
org $8000

xor a
ld hl,23755 ; basic başlangıç
clr ld (hl),0
inc hl
dec a
jr nz,clr

ld hl,data
ld de,23755
ld bc,32
ldir

; arada asıl kodu 23774'ten itibaren taşıma
; ve save rutini olacak
ret
;--------------------------------------------
; 2022 RANDOMIZE USR 23774 satırının dataları
;--------------------------------------------
data db $07,$e6,$0e,$00,$f9,$c0,$32,$33
db $37,$37,$34,$0e,$00,$00,$de,$5c
db $00,$0d,$80
;---------------------------------------------
ld a,1
out (254),a

; ld hl,maincode
; ld de,$8000
; ld bc,lenght
; ldir
; jp $8000
ret

end $8000

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #6 : 22 Nisan 2022, 17:56:03 »
@matahari açıklamalar için teşekkürler. Konuyu daha iyi anladım. Garbage baytlar kafa karıştırıyormuş.

Rica ederim, faydalı olabildiğime sevindim.

Basic dibine kod eklemek ve load"" code kullanmadan tüm kodu sadece load"" ile basic programıymış gibi yüklemek.

bkz: Speedlock 8)

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #7 : 22 Nisan 2022, 18:15:53 »
@matahari zaten speedlock konusunu okuduktan sonra problemi yazmaya karar verdim. Her zaman öğrenilecek bir şeyler vardır.

Çevrimdışı matahari

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 209
    • The Blog of Mert Börü
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #8 : 22 Nisan 2022, 18:40:47 »
zaten speedlock konusunu okuduktan sonra problemi yazmaya karar verdim.

Çok sevindim, @hades hocam.

RANDOMIZE USR'li versiyonu bitirdikten sonra belki bir de RANDOMIZE USR'siz (sadece PEEK/POKE kullanarak ON_ERROR_GOTO sistem değişkenlerini değiştiren) bir tane yazmayı düşünebilirsiniz. Böylece benim reverse engineering ile anlatmaya çalıştığım konuyu, siz literatürümüze doğrudan source code olarak sunabilirsiniz. Bizden sonrakiler için çok faydalı bir arşiv olur diye düşünüyorum. Elbette son karar sizin, benimkisi sadece bir temenni...

Her zaman öğrenilecek bir şeyler vardır.

Size içtenlikle katılıyorum. Bu yüzden forumdayız.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 175
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #9 : 22 Nisan 2022, 18:46:31 »
Dün ben de bu konuyu merak ettim, hafızada son satırı tekrar ederken gördüm, ama en son şimdilik bu kısmı es geçip, internetten hazır biçimde şu byte bloğunu buldum.

Kod: [Seç]
basic_loader:
  db $00,$0a,$0e,$00,$20,$fd,"32767",$0e,$00,$00,$ff,$7f,$00,$0d     ; 10 CLEAR 32767
  db $00,$14,$07,$00,$20,$ef,$22,$22,$20,$af,$0d                     ; 20 LOAD "" CODE
  db $00,$1e,$0f,$00,$20,$f9,$c0,"32768",$0e,$00,$00,$00,$80,$00,$0d ; 30 RANDOMIZE USR 32768
basic_loader_end:

SjASMPlus'da kodun sonuna şunları ekleyerek TAP üretebildim ve çalıştı.

Kod: [Seç]
    EMPTYTAP "first.tap"
    SAVETAP "first.tap", BASIC, "loader", basic_loader,basic_loader_end - basic_loader, 10
    SAVETAP "first.tap", CODE, "first", main, endOfCode - main, main

İşin güzel tarafı "şimdilik diğer kısımlara odaklanayım, daha sonra çözerim şu basic listing tarafını" diyordum ki @hades bu soruyu sordu @matahari de dört dörtlük cevapladı. Z80 tanrıları benim yanımda. :D

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #10 : 22 Nisan 2022, 21:55:55 »
Dün ben de bu konuyu merak ettim, hafızada son satırı tekrar ederken gördüm, ama en son şimdilik bu kısmı es geçip, internetten hazır biçimde şu byte bloğunu buldum.

Kod: [Seç]
basic_loader:
  db $00,$0a,$0e,$00,$20,$fd,"32767",$0e,$00,$00,$ff,$7f,$00,$0d     ; 10 CLEAR 32767
  db $00,$14,$07,$00,$20,$ef,$22,$22,$20,$af,$0d                     ; 20 LOAD "" CODE
  db $00,$1e,$0f,$00,$20,$f9,$c0,"32768",$0e,$00,$00,$00,$80,$00,$0d ; 30 RANDOMIZE USR 32768
basic_loader_end:

SjASMPlus'da kodun sonuna şunları ekleyerek TAP üretebildim ve çalıştı.

Kod: [Seç]
    EMPTYTAP "first.tap"
    SAVETAP "first.tap", BASIC, "loader", basic_loader,basic_loader_end - basic_loader, 10
    SAVETAP "first.tap", CODE, "first", main, endOfCode - main, main

İşin güzel tarafı "şimdilik diğer kısımlara odaklanayım, daha sonra çözerim şu basic listing tarafını" diyordum ki @hades bu soruyu sordu @matahari de dört dörtlük cevapladı. Z80 tanrıları benim yanımda. :D


Pasmo'da compile ederken --tapbas switch'i ekleyince basic loader bloğunu başına otomatik ekliyor, bence sjasmplus'da da vardır o özellik. ama neyse çözmüşsün. Ama burda hades'in sorduğu basic bloğu içinde code kısmınıda tek yüklemeyle çözmek.

Bu arada skate, senin ürettiğin kaset imajı, önce bir code block loader oluşturuyor, o basic de asm kodunu ayrıca ikinci bir blok olarak yüklüyor ve sonra önceden yüklediğin basic programı devam edip 30 satırda senin asm kodunu çalıştırıyor.

Hades istiyor ki, tek bir basic loader'i, hem basic'i hem asm kodu bir arada, tek seferde yüklesin ve yükleme bittiği gibi ikinci bir teyp yüklemesi olmasın, demo hemen çalışsın.
Benim söylediğim yöntem küçük introlar için en basit pratik yöntem. Tabi ötesi de mümkün, işte mataharinin speedlock yazısı var ERR_SP ayarlanarak yapılan bir sürü numara var orada, bir de bence tam bir sihirbazlık olan wizball loader'i var ki.. ne sihirbazlığı bildiğin cadı işi. Basic Loader yüklemeye başlıyor, kesmeden ekranı yüklüyor kesmeden programı da yüklüyor (halbuki spectrum hafıza haritasında önce ekran, sonra basic geliyor, arada geri dönüp o kısmı yüklüyor falan filan).

Dosyayı ekliyorum merak edenler specemu'dan yükleyip bakabilirler. 48k modunda hızlı yükleme yapmadan izlenebilir. Demo gibi bişey.

Çevrimdışı Skate

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 175
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #11 : 22 Nisan 2022, 22:10:33 »
Soru gayet açıktı. Ben @hades'in basic kodlarının durduğu bölgeyi görüp, oradaki duplicate junk datayı da görüp kafasının karışması, @matahari'nin de basic kodlarının olduğu bölgeyle ilgili yaptığı detaylı açıklamalara istinaden paylaştım bunu. Bu "al böyle de yaparsın" şeklinde paylaşılmış bir şey değil. Ben dün bunu yaparken de basic kodlarının durduğu bölgeyi inceledim, aynı şeye denk geldim. Ben bunu paylaşmadan sorun çözülmüştü zaten.

Ekşi sözlük kuralıdır. Bir enrty'de düzgün açıklama geldikten sonra muhabbet serbesttir. ;)

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #12 : 23 Nisan 2022, 00:51:34 »
Soru gayet açıktı. Ben @hades'in basic kodlarının durduğu bölgeyi görüp, oradaki duplicate junk datayı da görüp kafasının karışması, @matahari'nin de basic kodlarının olduğu bölgeyle ilgili yaptığı detaylı açıklamalara istinaden paylaştım bunu. Bu "al böyle de yaparsın" şeklinde paylaşılmış bir şey değil. Ben dün bunu yaparken de basic kodlarının durduğu bölgeyi inceledim, aynı şeye denk geldim. Ben bunu paylaşmadan sorun çözülmüştü zaten.

Ekşi sözlük kuralıdır. Bir enrty'de düzgün açıklama geldikten sonra muhabbet serbesttir. ;)
Muhabbet değil ya, o bilgi de önemli, bir eleştiri değildi, laf lafı açıyor şeklinde gitsin muhabbet. Fakat sen böyle diyince asıl soruyu hiç yanıtlamadığımızı gördüm.

Asıl soru şuydu:
"2022 RANDOMIZE USR ADRES" + kod
şeklindeki bir programda adres en düşük ne olabilir?
Hades başka birşey kast ediyordu ama yine de soruyu olduğu gibi cevaplamaya çalışalım.

Bunu şöyle düşünüyorum, oradaki ADRES makine kodumuzu koyabileceğimiz güvenli bir adres olmalı, makine kodumuz basic'in çalışmasına engel olmamalı (kod uygulandıktan ve tamamlandıktan sonra basic'e dönebilmeliyiz diyelim)

Basic'in başlangıcı 23755 olduğunu var sayalım (bazen ileri geri oynuyor takılan donanıma göre).

Şimdi burada birkaç düzeltme yapalım, randomize usr <adres> yerine randomize usr val "<adres>" yapalım 3 byte kazanalım (15 byte).

şu anda basic cursor'u 23770'e geldi.
bu durumda VARS vb ekleyelim, NXTLIN 23794'e geldi, girilecek satırla birlikte 35 byte diyelim, aslında eğer basic'i kasetten yükleyeceksek edeceksek buna gerek yok çünkü rom loader yükleme tamamlanınca otomatik basic'i çalıştırabiliyor ama geri döndüğümüzde halen bir satır ram olsa iyi olur.
eğer asm kodumuzu sihirli değneğimizle yerleştirebilirsek, bu durumda  23805 güvenlidir diyebiliriz.
eğer onu da kasetten yüklememiz gerekiyorsa LOAD "" CODE : komutu eklememiz gerek o da 5 byte tutuyor, dolayısıyla 23810 sanırım teorik güvenli en küçük adres olacaktır.

Ama burada tek yüklemede işlem hallolmuyor, fakat basic'in dayandığı dip burası olacaktır. Ekteki dosyada loader ve 36 byte'lık makine kodu bloğu var. Bunu 23810'a yerleştirdim ve ekranı ters çevirip (hades sanırım bu senin kodundu) tekrar basic'e dönüyor. Sorun yok. Basic umrumda değil diyorsan 23795 (NXTLIN) ya da olmazsa 23796 işi çözecektir. 

yetmedi, bir ihtimal daha var :D
sadece CODE bloğu vermek. Bunun için genelde tüm basic sistem değişkenlerini de dahil eden bir kayıt yapıyorsun ve yükleyecek kişiye, mesela 48k modunda load""code ile yüklemelisin diyorsun. SAVE "demo" code 22528, 1500
şeklinde kaydedip, yükleyenin konfigürasyonu ile senin konfigin tutması için dua ediyorsun :D hatta istersen biraz daha önden başlayıp ekrana grafik de yükleyebilirsin bu arada :D Ekte örnek veriyorum ship of the line oyunu...
 

Çevrimdışı hades

  • RAAT
  • Retro Meraklısı
  • *
  • İleti: 179
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #13 : 15 Ağustos 2022, 00:41:39 »
Basic programının dibine kod ekleyip oluşan programı sadece load komutuyla yükleme işini hallettim sayılır. Yıllar önce birileri yapmıştır mutlaka.

Program çalışınca 6161 RANDOMIZE USR 23755 şeklinde bir basic satırı üretiyor ve kısa bir transfer rutininin dibinden başlayan asıl kodu normal bir basic programı gibi save ediyor. Save işlemi bitince "C Nonsense in BASIC, 40:1" mesajı çıkıyor. Böyle bir mesajın çıkması da saçma zaten :)

6161 RANDOMIZE USR 23755 satırının satır numarası aslında JR $11 komutuna karşılık geliyor ve basic satırı çalışınca 23755 üzerinden $5CDE'deki relocator rutinine sıçrıyor.
Programın biraz daha geliştirilmesi gerekiyor.  Printer Buffer bölgesinde çalışacak şekilde ve mesela önceden $8000'den itibaren derlenen bir programı relocator rutinin dibine transfer edip save yapacak hale getirmeyi planlıyorum.


Kod: [Seç]
;********************************************************
; BASIC+CODE
; Basic programının dibine makine kodu ekleme ve kodu
; normal bir basic programı gibi save etme rutini

; 12.08.2017 HADES/RET - İlk denemeler
; 14.08.2022 Final öncesi denemeler
; Final versiyonu printer buffer'da çalışacak şekilde
; yapılacak.
;********************************************************
org $8000
;--------------------------------------------------------
; PROGRAM SAVE BÖLÜMÜ
;--------------------------------------------------------
; START TAPE... MESAJINI YAZDIR VE TUŞA BASILMASINI
; BEKLE (Bu kısım alıntıdır!!!)
;--------------------------------------------------------
start ld a,$fd ; Ensure that channel 'K' is open.
               call $1601
               xor a ; Signal 'first message'.
               ld de,$09a1 ;'Start tape, then press any key.'
               call $0c0a
               set 5,(iy+$02) ;Signal 'screen will require to be cleared'
               scf
               call $15d4 ;Bir tuşa basılmasını bekle
;;-------------------------------------------------------
; Header'i kaydet
;--------------------------------------------------------
               ld a,0
               ld ix,header
               ld de,17
               call $04c2
;--------------------------------------------------------
               ld b,20
wait halt
djnz wait
;--------------------------------------------------------
; Basic+code kısmını 23755'ten itibaren kopyala
;--------------------------------------------------------
ld hl,basic_line
ld de,23755
ld bc,finish-basic_line
ldir
;--------------------------------------------------------
; Programı kaydet
;--------------------------------------------------------
               ld a,$ff
               ld ix,23755
               ld de,finish-basic_line
               scf
               call $04c2
               ret
;========================================================
; TAPE HEADER BİLGİSİ
;========================================================
header;
file_type defb 0 ;dosya tipi: program
file_name defm "basic+code"
data_lenght defw finish-basic_line
start_line defw 6161 ;programın çalışma satırı
prog_lenght defw finish-basic_line
;--------------------------------------------------------
; 6161 RANDOMIZE USR 23755 satırının dataları (19 byte)
; ve relocator / çalıştırma rutini (14 byte)
;--------------------------------------------------------
basic_line db $18,$11,$0e,$00,$f9,$c0,$32,$33
db $37,$35,$35,$0e,$00,$00,$cb,$5c
db $00,$0d,$80
;--------------------------------------------------------
relocator ld hl,23755+(program-basic_line)
     ld de,$8000 ; programın gerçek adresi
     ld bc,finish-program
     ldir
     jp $8000 ; programın çalışma adresi
;========================================================
; DENEME AMAÇLI RUTİN
;========================================================
program defs 8192,0

call $0d6b
xxx ld a,r
out (254),a
jr xxx
;========================================================
finish:
end start ;$8000
;========================================

Çevrimdışı Ref

  • Yönetici
  • Özgür Retrocu
  • *
  • İleti: 2882
  • Advanced User Simulator
    • ae unutmadan
Ynt: Spectrum'la ilgili bir soru.
« Yanıtla #14 : 15 Ağustos 2022, 11:42:36 »
Basic programının dibine kod ekleyip oluşan programı sadece load komutuyla yükleme işini hallettim sayılır. Yıllar önce birileri yapmıştır mutlaka.

Program çalışınca 6161 RANDOMIZE USR 23755 şeklinde bir basic satırı üretiyor ve kısa bir transfer rutininin dibinden başlayan asıl kodu normal bir basic programı gibi save ediyor. Save işlemi bitince "C Nonsense in BASIC, 40:1" mesajı çıkıyor. Böyle bir mesajın çıkması da saçma zaten :)

6161 RANDOMIZE USR 23755 satırının satır numarası aslında JR $11 komutuna karşılık geliyor ve basic satırı çalışınca 23755 üzerinden $5CDE'deki relocator rutinine sıçrıyor.
Programın biraz daha geliştirilmesi gerekiyor.  Printer Buffer bölgesinde çalışacak şekilde ve mesela önceden $8000'den itibaren derlenen bir programı relocator rutinin dibine transfer edip save yapacak hale getirmeyi planlıyorum.



Henüz denemedim ama çok güzel bilgilerle dolu bir kod olmuş hades. Sayende bir sürü şey öğrendim yine. eline ve azmine sağlık.