эмуляция Orao

 


Еще одна платформа про которую "никто не слышал". Эмуляторов компьютера нашлось не так уж и много, многие не читаю кассеты, этот не пишет вообще. Информация о памяти нашлась на ретрофоруме:

$0000 - $5FFF : Memoria RAM.
$6000 - $7FFF : Memoria VRAM.
$8000 - $9FFF : Ubicación del sistema.
$A000 - $AFFF : Espacio reservado para la ampliación de RAM.
$B000 - $BFFF : DOS.
$C000 - $DFFF : Intérprete de BASIC
$E000 - #FFFF : Programa monitor y ROM del sistema.

подробнее:
* 0000 - 03FF - zero block (1K)
* 0400 - 5FFF - user RAM (23K)
* 6000 - 7FFF - video RAM (8K)
* 8000 - 9FFF - system locations (8K)
* 8000-87FE - keyboard
* 87FF - tape input register
* 8800 - 8fff - audio generation
* 9000 - 9fff - RS232
* A000 - AFFF - expansion (1K)
* B000 - BFFF - DOS (1K)
* C000 - DFFF - BASIC ROM (8K)
* E000 - FFFF - system ROM (8K)

Скачал эмуль, запустил. Первая засада - компьютер сидит в мониторе, непонятно, как выйти. Некоторые эмули ссылаются на команду BC, но чтение найденного документа Orao_prirucnik_102_103.pdf подсказало, что 

BC - This deletes the contents of the RAM and initializes BASIC. Entering Basic in this way is called COLD START BASIC.

BW -Calling Basic in this way is called HOT START Basic. With a hot start, Basic does not touch the contents of the memory, it remains preserved. A hot start is only possible if the Basic has already been cold started once and if the values have not been changed to zero page memory.

Дополнительно нашел описание команд монитора:
*Xnnnn - displays disassembled code at address nnnn
*X - continue disassembly from last used address
*Ennnn mmmm - print memory contents between nnnn and mmmm
*Hnnnn mmmm - print memory contents in both binary and ascii
*Mnnnn - modify memory at address nnnn
*Cnnnn mmmm - calculate sum starting from nnnn to mmmm. Used as a form of checksum.
*Fnnnn mmmm xx - fills memory between nnnn and mmmm with bytes xx
*Jnnnn - jump to address nnnn unconditionally
*Unnnn - jump to address nnnn as a subroutine (save return address to stack)
*#nnnn - convert hex nnnn to decimal
*Qnnnn mmmm iiii - move memory to target nnnn, source block starting from mmmm to iiii.
*Annnn - invoke mini-assembler, nnnn is the target where assembled code will be stored

Хорошо, вышел в Бейсик, запустил программу рисования на экране:

Оооо, у байта на экране обратный порядок следования битов. Учту на будущее.

Кстати, есть удобный ключ запуска: -lng en - язык программы
Еще одна проблема: выйдя из монитора, я не знаю, как его запустить. Смотрю исходник OraoJs-master.zip:

  this.pc = 0xFF89;
  this.sp = 0xFF;
  this.flags = 48;

набираю LNK65417  - я в мониторе. Описание USR еще больше запутало и затянуло исследование. Короче, миниассемблер не работает! Как я только не извращался - нифига не добился. Ладно, пишу программу на ассемблере ACME, надеясь создать файл .tap
 *=$1000
 !to "hl.bin", plain ; set output file and format
 !cpu 6502 ; set processor type

ldy #0
lp tya
v sta $6000
lda v+1
clc
adc #32
sta v+1
bcc noivh
inc v+2
noivh
iny
bne lp
rts

Всё чудесно, но эмуль тапку не читает, я перебрал все варианты, но безрезультатно. В голову приходит шальная мысль - добавить прогу к дампу памяти. Сохраняю дамп, получается  32775 байт - на 7 байт больше, чем положено. Пишу программу:

*m=AllocateMemory(65536)
ReadFile(0,"gg.dmp")
ReadData(0,*m,32775)
CloseFile(0)

ReadFile(0,"hl.bin")
ReadData(0,*m+$1007,37)

CreateFile(0,"gg1.dmp")
WriteData(0,*m,32775)
CloseFile(0)

FreeMemory(*m)
; IDE Options = PureBasic 5.30 (Windows - x86)
; CursorPosition = 6
; EnableUnicode
; EnableXP


Заработало! Краем глаза заметил описание процедур ROM, решил поиграть с точками. Как выяснилось, центр координат у экрана внизу вправо. Решил взглянуть на код, вдруг есть параметры у процедуры? Да, есть:
RAM:FE69 sub_FE69:                               ; CODE XREF: RAM:loc_FEF2p
RAM:FE69                                         ; RAM:FF5Cp
RAM:FE69                 TXA
RAM:FE6A                 PHA
RAM:FE6B                 TYA
RAM:FE6C                 PHA
RAM:FE6D                 JSR     sub_FE5A
RAM:FE70                 CLC
RAM:FE71                 LDX     $20A
RAM:FE74                 BMI     loc_FE7C
RAM:FE76                 BNE     loc_FE80
RAM:FE78                 ORA     ($E0),Y
RAM:FE7A                 BCC     loc_FE84
RAM:FE7C
RAM:FE7C loc_FE7C:                               ; CODE XREF: sub_FE69+Bj
RAM:FE7C                 EOR     ($E0),Y
RAM:FE7E                 BCC     loc_FE84
RAM:FE80
RAM:FE80 loc_FE80:                               ; CODE XREF: sub_FE69+Dj
RAM:FE80                 EOR     #$FF
RAM:FE82                 AND     ($E0),Y
RAM:FE84
RAM:FE84 loc_FE84:                               ; CODE XREF: sub_FE69+11j
RAM:FE84                                         ; sub_FE69+15j
RAM:FE84                 STA     ($E0),Y
RAM:FE86                 PLA
RAM:FE87                 TAY
RAM:FE88                 PLA
RAM:FE89                 TAX
RAM:FE8A                 RTS
RAM:FE8A ; End of function sub_FE69

Описание нашлось на забытой странице. Хотя, обойдусь и без этого. Значение в ячейке $020A влияет на выполнение процедуры:
0-поставить точку
1..127 - стереть точку
128..255 - инверсия точки.
Инверсия подошла, вышло 32 байта:
Продолжу позже.

Дополнение. Разобрался с миниассемблером : нужно было писать шестнадцатиричные цифры двумя символами - LDY #00, а не LDY #0 как я писал.

Подробнее об аппаратных ячейках, приведу набранный текст.

Опрос клавиатуры. Переводчик не справился с текстом, привожу адреса ячеек и значения клавиш. Да и описания немного различаются

87FC

Ex - lijevo(left)
Dx - gore(up)
Bx - dore
7x - desno(right)

87BE

Dx - J
Bx - K
Ex - L
7x - M

87ВE

Ex - E
Dx - Q
Bx - W
7x - 1

87FA

Ex - PF1
Dx - PF2
Bx - PF3
7x - PF4

877E

Ex - D
Dx - A
Bx - S
7x - Y

83FE

Ex - P
Dx - D
Bx - S
7x - +

87F6

Ex - R
Dx - Z
Bx - T
7x - 6

86FE

Ex - F
Dx - H
Bx - G
7x - N

87FD

Dx - CTL
Ex - CR

87EE

Ex - O
Dx - I
Bx - U
7x - 7

85FE

Ex - C
Dx - C
Bx - Z
7x - *

87FB
Ex - SPC
Dx - Shift

;A key
LDA 877E ;$d0=11010000
and #20  ;$20=00100000

;test Q&S
L2000 LDA 87DE
L2003 AND #$20 ;Q?
L2005 BNE L2000
L2007 LDA 877E
L2009 AND #$40 ;S?
L200C BNE L2000
L200E LDA #$41 ;'A'
L2010 JSR FFF1 ; print 'A'
L2013 JMP L2000

;Potprogram za unos znaka s tastaure(Subroutine for entering a character from the keyboard)
1000 JSR E500
1002 LDA FC
1005 CMP #$41
1007 BEQ 1011
1009 LDA #$40
100B JSR FFF1
100E JMP 1000
1011 CLC
1012 RTS

Звук

1000 LDX #$10
1002 LDY #$FF
1004 DEY
1005 BNE 1004
1007 BIT 8800
100A DEX
100B BNE 1002
100D RTS

1000 LDX #$FF
1002 LDY #$FF
1004 TYA
1005 STY 8800
1008 DEY
1009 BNE 1000
100B TAY
100C DEY
100D BNE 1004
100F DEX
1010 TXA
1011 TAY
1012 DEY
1013 BNE 1004
1015 RTS

1000 LDA #$FF
1002 STA 20
1004 LDX #$FE
1006 LDY 20
1008 DEY
1009 BNE 1008
100B BIT 8800
100E DEC 20
1010 DEX
1011 BNE 1006
1013 RTS

1000 LDX #$FF
1002 LDY #$FF
1004 TYA
1005 STY 8800
1008 DEY
1009 BNE 1008
100B TAY
100C DEX
100D DEY
100E BNE 1004
1010 JSR E5B0 ;da li je pritisnut koji taster? which key was pressed?
1013 BCC 1000 ;ako nije idi na 1000 if not go to 1000
1015 JSR E500 ;taster je pritisnut, aji koji? the key is pressed, which one?
1018 CMP #41  ;da li je pritisnuto "A"? is "A" pressed?
101A BNE 1000 ;ako nije idi na pocetak if not go to the beginning
101C CLC
101D RTS

1000 JSR E5B0
1003 BCC 1000
1005 LDX FA
1007 DEX
1008 BNE 1007
100A BIT 8800
100D JMP 1000

;DVOKANALNOG ZVUK
2000 LDA #$FF
2002 STA 20
2004 LDA #$FE
2006 STA 21
2008 DEX
2009 BNE 2010
200B BIT 8800
200E LDX 20
2010 DEY
2011 BNE 2008
2013 BIT 8800
2016 LDY 21
2018 JMP 2008

;TROKANALNOG ZVUKU
1000 LDA #$FF
1002 STA E2
1004 LDA #$FD
1006 STA E3
1008 LDA #$FB
100A STA E0
100C DEX
100D BNE 1014
100F BIT 8800
1012 LDX E2
1014 DEY
1015 BNE 101C
1017 BIT 8800
101A LDY E3
101C DEC $E0
101E BNE 100C
1020 BIT 8800
1023 STA E0
1024 JMP 1000

Графика.

;CIR
1000 LDA #$80
1002 STA E2 ;X
1004 STA E3 ;Y
1006 LDA #$50 ;polumer kruznice(radius of the circle)
1008 STA F8
100A JSR FF06
100D RTS

;DRAW
1000 LDA #$00
1002 STA E3 ;Y1 koordinata pacetne toske linije(coordinate of the initial longing line)
1004 STA E4 ;X2 koordinata zavrsne toske linije
1006 LDA #$FF
1008 STA E2 ;X1 koordinata zavrsne toske linije(the coordinate of the end point of the line)
100A STA E5 ;Y2 koordinata zavrsne toske linije
100C JSR FE8B
100F RTS

;PLOT, E2=X,E3=Y
1000 LDA #$80
1002 STA E2 ;X
1004 STA E4 ;Y
1006 JSR FE69
1009 RTS
;020A: b7=1 = inverse,<>0 - reset

;Primjer: nacrtat cemo, tocku po tocku, dijagonal ekrana
;Example: we will draw, point by point, the diagonal of the screen
1000 LDA #$FF
1002 STA E2
1004 STA E3
1006 JSR FE69
1009 DEC E2
100B DEC E3
100D BNE 1006
100F RTS

Прочие процедуры.
;rutina ispisivanja numerickih vrijednosti
;routine of printing numerical values
1000 LDA #$41
1002 JSR EB03
1005 RTS
;result:
*U1000
41

1000 LDA #$00
1002 STA F7 ;visi dio(hanging part)
1004 LDA #$FF
1006 STA F6 ;nizi dio(lower part)
1008 JSR E882
100B JSR EF86
100E RTS
;*U1000
;255

;rutina za pozicioniranje kursora
;cursor positioning routine
2000 LDA #$05
2002 STA E8 ; trebamo zapisati RED ???we need to write RED
2004 LDA #$00
2006 STA E9 ; KOLONU
2008 JSR E93D
200B LDY #$00
200D LDA #$11
200F JSR E63B
2012 RTS

;rutina ispisivanja stringa
;string printing routine
1000 LDY #$00
1002 LDA #$11
1004 JSR E63B
1007 RTS
1100 AA 4D
...
1113 AA 04

;rutina ispisivanja karaktera
;character printing routine
1000 LDA #441
1002 JSR FFF1
1005 RTS
;result
;*A1000
;AU1000
;*_

Здесь архив с документацией и утилита bin2dmp.

Комментарии