	; Program za posxiljanje vsebine trdega diska Partnerja preko RS-232
	; Alternativna verzija, ki vecxino dela opravi v BASICu
	; Alternativna verzija slednje, ki posxlje vsak sektor enkrat, vendar
	; vsak bajt (tudi checksum) trikrat, da se na strani prejemnika
	; uporablja "glasovanje"
	; Matej Horvat
	; 21. april 2017

	; To ni samostojen program, temvecx procedura, ki jo klicxemo iz
	; Microsoft BASICa s programom:

	; 10 A% = &H7000: REM Sem nalozximo strojno kodo
	; 30 DEF USR0 = A%: REM Vstopna tocxka za SETDMA
	; 31 DEF USR1 = A% + 2: REM Vstopna tocxka za SETTRK
	; 32 DEF USR2 = A% + 4: REM Vstopna tocxka za SETSEC
	; 33 DEF USR3 = A% + 6: REM Vstopna tocxka za READ
	; 34 DEF USR4 = A% + 8: REM Vstopna tocxka za posxiljanje
	; 39 I% = A%
	; 40 READ B%
	; 50 IF B% = -1 THEN GOTO 90
	; 60 POKE I%, B%
	; 70 I% = I% + 1
	; 80 GOTO 40
	; 90 Z% = USR0(0): REM Klicxemo SETDMA
	; 100 FOR T% = 0 TO 1223: REM Sled
	; 110 POKE A% + 10, T% AND 255: POKE A% + 11, (T% \ 256) AND 255
	; 120 Z% = USR1(0): REM Klicxemo SETTRK
	; 130 FOR S% = 1 TO 32: REM Sektor
	; 140 POKE A% + 10, S%: POKE A% + 11, 0
	; 150 Z% = USR2(0): REM Klicxemo SETSEC
	; 160 FOR I% = 1 TO 10
	; 165 PRINT "Sled"; T%; "sektor"; S%; "poskus"; I%
	; 170 Z% = USR3(0): REM Klicxemo READ
	; 180 IF PEEK(A% + 10) = 0 THEN GOTO 220
	; 190 NEXT I%
	; 200 PRINT "Napaka!": END
	; 220 Z% = USR4(0): REM Posxljemo sektor in checksum
	; 240 NEXT S%
	; 250 NEXT T%
	; 260 PRINT "Konec!"
	; 270 DATA ...: REM Vstavi strojno kodo sem

	; Pred zacxetkom je treba:
	; 1. Izvesti: DEVICE LPT[NOX
	; 2. Zagnati GRMT20.
	; 3. Ga prekiniti s SHIFT+BRK; tako zagotovimo pravilno
	;    inicializacijo RS-232.
	; 4. Zagnati MBASIC s parametrom: /M:&H7000

	; ----------------------------------------

	org 07000h

	jr SETDMA	; ORG + 0
	jr SETTRK	; ORG + 2
	jr SETSEC	; ORG + 4
	jr READ		; ORG + 6
	jr PosljiSektor	; ORG + 8
Param	dw 0		; ORG + 10; se uporablja za prenasxanje informacij

	; ----------------------------------------

SETDMA:
	; Nastavimo naslov, na katerega bomo brali sektorje.
	ld a, 12	; SETDMA
	ld bc, Buffer
	jr BIOS

	; ----------------------------------------

SETTRK:
	; Premaknemo se na zxeleno sled.
	ld a, 10	; SETTRK
	jr ParamInBIOS

	; ----------------------------------------

SETSEC:
	; Premaknemo se na zxeleni sektor.
	ld a, 11	; SETSEC
	; (se nadaljuje spodaj)

	; ----------------------------------------

ParamInBIOS:
	; Klicxe BIOS funkcijo z BC = (Param).

	ld bc, (Param)
	; (se nadaljuje spodaj)

	; ----------------------------------------

BIOS:
	; Klicxe BIOS funkcijo.
	; Na CP/M 3 ne moremo direktno klicati BIOS funkcij (s skokom
	; v tabelo JP insxtrukcij, ki jo dobimo na naslovu 0001h),
	; temvecx moramo uporabiti BDOS funkcijo 50, ki poklicxe zxeleno
	; BIOS funkcijo za nas; to je potrebno, ker so BIOS funkcije
	; lahko implementirane v drugi banki.

	; IN:
	; A = sxt. funkcije (0 za BOOT, 1 za WBOOT, 2 za CONST, itd.)
	; BC = parameter, kot dolocxa funkcija

	; OUT:
	; Odvisno od funkcije

	; Postavimo parametre. Mi potrebujemo le BC.
	ld (.par), a	; Sxtevilka funkcije
	ld (.par+2), bc

	; Klicxemo BDOS funkcijo "use the BIOS"
	ld c, 50
	ld de, .par
	jp 5

.par:
	; (Ta buffer je nacxeloma dolg 8 bajtov, vendar mi posredujemo
	; samo sxtevilko funkcije, B, in C. Za druge registre nam je
	; vseeno, ker jih BIOS funkcije, ki jih klicxejo, ne
	; uposxtevajo.)
	db 0, 0, 0, 0

	; ----------------------------------------

READ:
	; Preberemo sektor in vrnemo status.
	ld a, 13	; READ
	call BIOS
	ld (Param), a
	ret

	; ----------------------------------------

PosljiSektor:
	; Posxlje sektor in checksum.

	ld hl, Buffer
	ld b, 0		; 256 ponovitev notranje zanke
	ld c, b		; Checksum := 0

.naslednjiBajt:
	; Posxljemo en bajt.
	ld a, (hl)
	call PosljiBajt

	; Prisxtejemo k checksumu.
	add a, c
	ld c, a

	; Gremo na naslednji bajt.
	inc hl
	djnz .naslednjiBajt

	; Posxljemo checksum.
	ld a, c
	; (se nadaljuje spodaj)

	; ----------------------------------------

PosljiBajt:
	; Posxlje bajt po serijskem portu. Ista vrednost se posxlje
	; trikrat; prejemnik dekodira z "glasovanjem".

	; IN:
	; A = bajt

	push bc

	ld b, 3
.seEnkrat:
	; Cxakamo, dokler serijski port ni pripravljen na naslednji bajt.
	push af
.cakaj:
	in a, (0DBh)
	and 4
	jr z, .cakaj
	pop af

	; Posxljemo bajt.
	out (0DAh), a

	djnz .seEnkrat

	pop bc

	ret

	; ----------------------------------------

Buffer:
	; Sem se berejo sektorji.