1999-03-31: Updated to version 1.10

This commit is contained in:
Gwenhael Le Moine 2024-03-19 22:24:30 +01:00
parent b78fce7dbf
commit dc12da9a17
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
96 changed files with 15931 additions and 7610 deletions

1
BEEP.EXT Normal file
View file

@ -0,0 +1 @@
017A6:81B1

BIN
CP_48G3.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

595
CP_48G3.KML Normal file
View file

@ -0,0 +1,595 @@
Global
Print "=========================================================="
Print ""
Print "This graphic is by Casey Patterson."
Print "pattersc@gulftel.com"
Print ""
Print "Come to my page to get more graphics for your Win48!!!"
Print ""
Print "http://www.gulftel.com/~pattersc/win48/"
Print ""
Print "=========================================================="
Print ""
Print "A few improvements by Sebastien Carlier, the author of Emu48."
Print "Please visit the Emu48 Official Homepage :"
Print "http://www.geocities.com/CapeCanaveral/5948/index.html"
Print ""
Print "Thanks for using Emu48 !"
Print ""
Print "=========================================================="
Title "Casey's Gx with Toolbar and Touch Screen"
Author "Casey Patterson && Sebastien Carlier"
Model "G"
Rom "ROM.48G"
Patch "BEEP.EXT"
Bitmap "cp_48g3.bmp"
Debug 1
End
Background
Offset 0 0
Size 302 517
End
Lcd
Zoom 2
Offset 20 52
Color 0 255 255 255
Color 1 255 255 255
Color 2 255 255 255
Color 3 255 255 255
Color 4 255 255 255
Color 5 255 255 255
Color 6 255 255 255
Color 7 255 255 255
Color 8 240 240 240
Color 9 225 225 225
Color 10 210 210 210
Color 11 195 195 195
Color 12 180 180 180
Color 13 165 165 165
Color 14 150 150 150
Color 15 135 135 135
Color 16 120 120 120
Color 17 105 105 105
Color 18 90 90 90
Color 19 75 75 75
Color 20 60 60 60
Color 21 45 45 45
Color 22 30 30 30
Color 23 15 15 15
Color 24 0 0 0
Color 25 0 0 0
Color 26 0 0 0
Color 27 0 0 0
Color 28 0 0 0
Color 29 0 0 0
Color 30 0 0 0
Color 31 0 0 0
End
Annunciator 1
Size 15 11
Offset 41 37
Down 16 517
End
Annunciator 2
Size 15 11
Offset 82 37
Down 32 517
End
Annunciator 3
Size 13 11
Offset 123 37
Down 48 517
End
Annunciator 4
Size 15 11
Offset 164 37
Down 64 517
End
Annunciator 5
Size 11 11
Offset 205 37
Down 80 517
End
Annunciator 6
Size 12 11
Offset 246 37
Down 96 517
End
Button 11
Size 37 26
Offset 8 190
Down 0 528
OutIn 1 16
End
Button 12
Size 37 26
Offset 58 190
Down 0 528
OutIn 8 16
End
Button 13
Size 37 26
Offset 108 190
Down 0 528
OutIn 8 8
End
Button 14
Size 37 26
Offset 158 190
Down 0 528
OutIn 8 4
End
Button 15
Size 37 26
Offset 208 190
Down 0 528
OutIn 8 2
End
Button 16
Size 37 26
Offset 258 190
Down 0 528
OutIn 8 1
End
Button 21
Size 37 26
Offset 8 227
Down 37 528
OutIn 2 16
End
Button 22
Size 38 26
Offset 57 227
OutIn 7 16
Down 74 528
End
Button 23
Size 37 26
Offset 108 227
OutIn 7 8
Down 112 528
End
Button 24
Size 37 26
Offset 158 227
OutIn 7 4
Down 149 528
End
Button 25
Size 37 26
Offset 208 227
OutIn 7 2
Down 186 528
End
Button 26
Size 37 26
Offset 258 227
OutIn 7 1
Down 223 528
End
Button 31
Size 37 26
Offset 8 264
OutIn 0 16
Down 260 528
End
Button 32
Size 37 26
Offset 58 264
OutIn 6 16
Down 0 554
End
Button 33
Size 37 26
Offset 108 264
OutIn 6 8
Down 37 554
End
Button 34
Size 37 26
Offset 158 264
OutIn 6 4
Down 74 554
End
Button 35
Size 37 26
Offset 208 264
OutIn 6 2
Down 111 554
End
Button 36
Size 37 26
Offset 258 264
OutIn 6 1
Down 148 554
End
Button 41
Size 37 26
Offset 8 301
OutIn 3 16
Down 185 554
End
Button 42
Size 37 26
Offset 58 301
OutIn 5 16
Down 222 554
End
Button 43
Size 37 26
Offset 108 301
OutIn 5 8
Down 259 554
End
Button 44
Size 37 26
Offset 158 301
OutIn 5 4
Down 0 580
End
Button 45
Size 37 26
Offset 208 301
OutIn 5 2
Down 37 580
End
Button 46
Size 37 26
Offset 258 301
OutIn 5 1
Down 74 580
End
Button 51
Size 87 26
Offset 8 338
OutIn 4 16
Down 111 580
End
Button 52
Size 37 26
Offset 108 338
OutIn 4 8
Down 198 580
End
Button 53
Size 37 26
Offset 158 338
OutIn 4 4
Down 235 580
End
Button 54
Size 37 26
Offset 208 338
OutIn 4 2
Down 0 606
End
Button 55
Size 37 26
Offset 258 338
OutIn 4 1
Down 37 606
End
Button 61
Size 37 26
Offset 8 375
OutIn 3 32
Down 74 606
End
Button 62
Size 48 26
Offset 67 375
OutIn 3 8
Down 222 606
End
Button 63
Size 48 26
Offset 127 375
OutIn 3 4
Down 0 632
End
Button 64
Size 48 26
Offset 187 375
OutIn 3 2
Down 48 632
End
Button 65
Size 48 26
Offset 247 375
OutIn 3 1
Down 96 632
End
Button 71
Size 37 26
Offset 8 412
OutIn 2 32
Down 111 606
End
Button 72
Size 48 26
Offset 67 412
OutIn 2 8
Down 144 632
End
Button 73
Size 48 26
Offset 127 412
OutIn 2 4
Down 192 632
End
Button 74
Size 48 26
Offset 187 412
OutIn 2 2
Down 240 632
End
Button 75
Size 48 26
Offset 247 412
OutIn 2 1
Down 0 658
End
Button 81
Size 37 26
Offset 8 449
OutIn 1 32
Down 148 606
End
Button 82
Size 48 26
Offset 67 449
OutIn 1 8
Down 48 658
End
Button 83
Size 48 26
Offset 127 449
OutIn 1 4
Down 96 658
End
Button 84
Size 48 26
Offset 187 449
OutIn 1 2
Down 144 658
End
Button 85
Size 48 26
Offset 247 449
OutIn 1 1
Down 192 658
End
Button 91
Size 37 26
Offset 8 486
OutIn 0 32768
Down 185 606
End
Button 92
Size 48 26
Offset 67 486
OutIn 0 8
Down 240 658
End
Button 93
Size 48 26
Offset 127 486
OutIn 0 4
Down 0 684
End
Button 94
Size 48 26
Offset 187 486
OutIn 0 2
Down 48 684
End
Button 95
Size 48 26
Offset 247 486
OutIn 0 1
Down 96 684
End
Button 101
Type 3
Size 42 16
Offset 20 164
Virtual
OnDown
Press 11
End
OnUp
Release 11
End
End
Button 102
Type 3
Size 42 16
Offset 64 164
Virtual
OnDown
Press 12
End
OnUp
Release 12
End
End
Button 103
Type 3
Size 42 16
Offset 108 164
Virtual
OnDown
Press 13
End
OnUp
Release 13
End
End
Button 104
Type 3
Size 42 16
Offset 152 164
Virtual
OnDown
Press 14
End
OnUp
Release 14
End
End
Button 105
Type 3
Size 42 16
Offset 196 164
Virtual
OnDown
Press 15
End
OnUp
Release 15
End
End
Button 106
Type 3
Size 42 16
Offset 240 164
Virtual
OnDown
Press 16
End
OnUp
Release 16
End
End
Button 107
Type 4
Size 262 112
Offset 20 52
Down 20 52
NoHold
End
Button 108
Size 10 12
Offset 288 168
Down 288 591
Virtual
OnDown
Press 26
End
OnUp
Release 26
End
End
Button 110
Type 1
Size 23 22
Offset 23 5
NoHold
OnUp
MenuItem 1
End
End
Button 111
Type 1
Size 23 22
Offset 46 5
NoHold
OnUp
MenuItem 2
End
End
Button 112
Type 1
Size 23 22
Offset 69 5
NoHold
OnUp
MenuItem 3
End
End
Button 113
Type 1
Size 23 22
Offset 97 5
NoHold
OnUp
MenuItem 6
End
End
Button 114
Type 1
Size 23 22
Offset 125 5
NoHold
OnUp
MenuItem 8
End
End
Button 115
Type 1
Size 23 22
Offset 148 5
NoHold
OnUp
MenuItem 7
End
End
Button 116
Type 1
Size 23 22
Offset 171 5
NoHold
OnUp
MenuItem 17
End
End
Button 117
Type 1
Size 23 22
Offset 199 5
NoHold
OnUp
MenuItem 9
End
End
Button 118
Type 1
Size 23 22
Offset 222 5
NoHold
OnUp
MenuItem 10
End
End
Button 119
Type 1
Size 23 22
Offset 250 5
NoHold
OnUp
MenuItem 11
End
End
Include "Keyboard.kmi"

BIN
CP_48S3.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

587
CP_48S3.KML Normal file
View file

@ -0,0 +1,587 @@
Global
Print "=========================================================="
Print ""
Print "This graphic is by Casey Patterson."
Print "pattersc@gulftel.com"
Print ""
Print "Come to my page to get more graphics for your Win48!!!"
Print ""
Print "http://www.gulftel.com/~pattersc/win48/"
Print ""
Print "=========================================================="
Title "Casey's Sx with Toolbar and Touch Screen"
Author "Casey Patterson"
Model "S"
Rom "ROM.48S"
Patch "BEEP.EXT"
Debug 0
Bitmap "cp_48s3.bmp"
End
Background
Offset 0 0
Size 302 517
End
Lcd
Zoom 2
Offset 20 52
Color 0 255 255 255
Color 1 255 255 255
Color 2 255 255 255
Color 3 240 240 240
Color 4 225 225 225
Color 5 210 210 210
Color 6 195 195 195
Color 7 180 180 180
Color 8 165 165 165
Color 9 150 150 150
Color 10 135 135 135
Color 11 120 120 120
Color 12 105 105 105
Color 13 90 90 90
Color 14 75 75 75
Color 15 60 60 60
Color 16 45 45 45
Color 17 30 30 30
Color 18 15 15 15
Color 19 0 0 0
Color 20 0 0 0
Color 21 0 0 0
Color 22 0 0 0
Color 23 0 0 0
Color 24 0 0 0
Color 25 0 0 0
Color 26 0 0 0
Color 27 0 0 0
Color 28 0 0 0
Color 29 0 0 0
Color 30 0 0 0
Color 31 0 0 0
End
Annunciator 1
Size 15 11
Offset 41 37
Down 16 517
End
Annunciator 2
Size 15 11
Offset 82 37
Down 32 517
End
Annunciator 3
Size 13 11
Offset 123 37
Down 48 517
End
Annunciator 4
Size 15 11
Offset 164 37
Down 64 517
End
Annunciator 5
Size 11 11
Offset 205 37
Down 80 517
End
Annunciator 6
Size 12 11
Offset 246 37
Down 96 517
End
Button 11
Size 37 26
Offset 8 190
Down 0 528
OutIn 1 16
End
Button 12
Size 37 26
Offset 58 190
Down 0 528
OutIn 8 16
End
Button 13
Size 37 26
Offset 108 190
Down 0 528
OutIn 8 8
End
Button 14
Size 37 26
Offset 158 190
Down 0 528
OutIn 8 4
End
Button 15
Size 37 26
Offset 208 190
Down 0 528
OutIn 8 2
End
Button 16
Size 37 26
Offset 258 190
Down 0 528
OutIn 8 1
End
Button 21
Size 37 26
Offset 8 227
Down 37 528
OutIn 2 16
End
Button 22
Size 38 26
Offset 57 227
OutIn 7 16
Down 74 528
End
Button 23
Size 37 26
Offset 108 227
OutIn 7 8
Down 112 528
End
Button 24
Size 37 26
Offset 158 227
OutIn 7 4
Down 149 528
End
Button 25
Size 37 26
Offset 208 227
OutIn 7 2
Down 186 528
End
Button 26
Size 37 26
Offset 258 227
OutIn 7 1
Down 223 528
End
Button 31
Size 37 26
Offset 8 264
OutIn 0 16
Down 260 528
End
Button 32
Size 37 26
Offset 58 264
OutIn 6 16
Down 0 554
End
Button 33
Size 37 26
Offset 108 264
OutIn 6 8
Down 37 554
End
Button 34
Size 37 26
Offset 158 264
OutIn 6 4
Down 74 554
End
Button 35
Size 37 26
Offset 208 264
OutIn 6 2
Down 111 554
End
Button 36
Size 37 26
Offset 258 264
OutIn 6 1
Down 148 554
End
Button 41
Size 37 26
Offset 8 301
OutIn 3 16
Down 185 554
End
Button 42
Size 37 26
Offset 58 301
OutIn 5 16
Down 222 554
End
Button 43
Size 37 26
Offset 108 301
OutIn 5 8
Down 259 554
End
Button 44
Size 37 26
Offset 158 301
OutIn 5 4
Down 0 580
End
Button 45
Size 37 26
Offset 208 301
OutIn 5 2
Down 37 580
End
Button 46
Size 37 26
Offset 258 301
OutIn 5 1
Down 74 580
End
Button 51
Size 87 26
Offset 8 338
OutIn 4 16
Down 111 580
End
Button 52
Size 37 26
Offset 108 338
OutIn 4 8
Down 198 580
End
Button 53
Size 37 26
Offset 158 338
OutIn 4 4
Down 235 580
End
Button 54
Size 37 26
Offset 208 338
OutIn 4 2
Down 0 606
End
Button 55
Size 37 26
Offset 258 338
OutIn 4 1
Down 37 606
End
Button 61
Size 37 26
Offset 8 375
OutIn 3 32
Down 74 606
End
Button 62
Size 48 26
Offset 67 375
OutIn 3 8
Down 222 606
End
Button 63
Size 48 26
Offset 127 375
OutIn 3 4
Down 0 632
End
Button 64
Size 48 26
Offset 187 375
OutIn 3 2
Down 48 632
End
Button 65
Size 48 26
Offset 247 375
OutIn 3 1
Down 96 632
End
Button 71
Size 37 26
Offset 8 412
OutIn 2 32
Down 111 606
End
Button 72
Size 48 26
Offset 67 412
OutIn 2 8
Down 144 632
End
Button 73
Size 48 26
Offset 127 412
OutIn 2 4
Down 192 632
End
Button 74
Size 48 26
Offset 187 412
OutIn 2 2
Down 240 632
End
Button 75
Size 48 26
Offset 247 412
OutIn 2 1
Down 0 658
End
Button 81
Size 37 26
Offset 8 449
OutIn 1 32
Down 148 606
End
Button 82
Size 48 26
Offset 67 449
OutIn 1 8
Down 48 658
End
Button 83
Size 48 26
Offset 127 449
OutIn 1 4
Down 96 658
End
Button 84
Size 48 26
Offset 187 449
OutIn 1 2
Down 144 658
End
Button 85
Size 48 26
Offset 247 449
OutIn 1 1
Down 192 658
End
Button 91
Size 37 26
Offset 8 486
OutIn 0 32768
Down 185 606
End
Button 92
Size 48 26
Offset 67 486
OutIn 0 8
Down 240 658
End
Button 93
Size 48 26
Offset 127 486
OutIn 0 4
Down 0 684
End
Button 94
Size 48 26
Offset 187 486
OutIn 0 2
Down 48 684
End
Button 95
Size 48 26
Offset 247 486
OutIn 0 1
Down 96 684
End
Button 101
Type 3
Size 42 16
Offset 20 164
Virtual
OnDown
Press 11
End
OnUp
Release 11
End
End
Button 102
Type 3
Size 42 16
Offset 64 164
Virtual
OnDown
Press 12
End
OnUp
Release 12
End
End
Button 103
Type 3
Size 42 16
Offset 108 164
Virtual
OnDown
Press 13
End
OnUp
Release 13
End
End
Button 104
Type 3
Size 42 16
Offset 152 164
Virtual
OnDown
Press 14
End
OnUp
Release 14
End
End
Button 105
Type 3
Size 42 16
Offset 196 164
Virtual
OnDown
Press 15
End
OnUp
Release 15
End
End
Button 106
Type 3
Size 42 16
Offset 240 164
Virtual
OnDown
Press 16
End
OnUp
Release 16
End
End
Button 107
Type 4
Size 262 112
Offset 20 52
Down 20 52
NoHold
End
Button 108
Size 10 12
Offset 288 168
Down 288 591
Virtual
OnDown
Press 26
End
OnUp
Release 26
End
End
Button 110
Type 1
Size 23 22
Offset 23 5
NoHold
OnUp
MenuItem 1
End
End
Button 111
Type 1
Size 23 22
Offset 46 5
NoHold
OnUp
MenuItem 2
End
End
Button 112
Type 1
Size 23 22
Offset 69 5
NoHold
OnUp
MenuItem 3
End
End
Button 113
Type 1
Size 23 22
Offset 97 5
NoHold
OnUp
MenuItem 6
End
End
Button 114
Type 1
Size 23 22
Offset 125 5
NoHold
OnUp
MenuItem 8
End
End
Button 115
Type 1
Size 23 22
Offset 148 5
NoHold
OnUp
MenuItem 7
End
End
Button 116
Type 1
Size 23 22
Offset 171 5
NoHold
OnUp
MenuItem 17
End
End
Button 117
Type 1
Size 23 22
Offset 199 5
NoHold
OnUp
MenuItem 9
End
End
Button 118
Type 1
Size 23 22
Offset 222 5
NoHold
OnUp
MenuItem 10
End
End
Button 119
Type 1
Size 23 22
Offset 250 5
NoHold
OnUp
MenuItem 11
End
End
Include "Keyboard.kmi"

BIN
Convert.exe Normal file

Binary file not shown.

BIN
DEFAULTG.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

392
DEFAULTG.KML Normal file
View file

@ -0,0 +1,392 @@
Global
Title "Emu48's Default Faceplate for HP48G/GX"
Author "Sebastien Carlier"
Model "G"
Rom "ROM.48G"
Patch "BEEP.EXT"
Debug 0
Bitmap "DEFAULTG.BMP"
End
Background
Offset 0 0
Size 302 485
End
Lcd
Zoom 2
Offset 20 20
Color 0 255 255 255
Color 1 255 255 255
Color 2 255 255 255
Color 3 255 255 255
Color 4 255 255 255
Color 5 255 255 255
Color 6 255 255 255
Color 7 255 255 255
Color 8 240 240 240
Color 9 225 225 225
Color 10 210 210 210
Color 11 195 195 195
Color 12 180 180 180
Color 13 165 165 165
Color 14 150 150 150
Color 15 135 135 135
Color 16 120 120 120
Color 17 105 105 105
Color 18 90 90 90
Color 19 75 75 75
Color 20 60 60 60
Color 21 45 45 45
Color 22 30 30 30
Color 23 15 15 15
Color 24 0 0 0
Color 25 0 0 0
Color 26 0 0 0
Color 27 0 0 0
Color 28 0 0 0
Color 29 0 0 0
Color 30 0 0 0
Color 31 0 0 0
End
Annunciator 1
Size 15 11
Offset 41 4
Down 16 485
End
Annunciator 2
Size 15 11
Offset 82 4
Down 32 485
End
Annunciator 3
Size 13 11
Offset 123 4
Down 48 485
End
Annunciator 4
Size 15 11
Offset 164 4
Down 64 485
End
Annunciator 5
Size 11 11
Offset 205 4
Down 80 485
End
Annunciator 6
Size 12 11
Offset 246 4
Down 96 485
End
Button 11
Type 1
Size 36 25
Offset 8 158
OutIn 1 16
End
Button 12
Type 1
Size 36 25
Offset 58 158
OutIn 8 16
End
Button 13
Type 1
Size 36 25
Offset 108 158
OutIn 8 8
End
Button 14
Type 1
Size 36 25
Offset 158 158
OutIn 8 4
End
Button 15
Type 1
Size 36 25
Offset 208 158
OutIn 8 2
End
Button 16
Type 1
Size 36 25
Offset 258 158
OutIn 8 1
End
Button 21
Type 1
Size 36 25
Offset 8 195
OutIn 2 16
End
Button 22
Type 1
Size 36 25
Offset 58 195
OutIn 7 16
End
Button 23
Type 1
Size 36 25
Offset 108 195
OutIn 7 8
End
Button 24
Type 1
Size 36 25
Offset 158 195
OutIn 7 4
End
Button 25
Type 1
Size 36 25
Offset 208 195
OutIn 7 2
End
Button 26
Type 1
Size 36 25
Offset 258 195
OutIn 7 1
End
Button 31
Type 1
Size 36 25
Offset 8 232
OutIn 0 16
End
Button 32
Type 1
Size 36 25
Offset 58 232
OutIn 6 16
End
Button 33
Type 1
Size 36 25
Offset 108 232
OutIn 6 8
End
Button 34
Type 1
Size 36 25
Offset 158 232
OutIn 6 4
End
Button 35
Type 1
Size 36 25
Offset 208 232
OutIn 6 2
End
Button 36
Type 1
Size 36 25
Offset 258 232
OutIn 6 1
End
Button 41
Type 1
Size 36 25
Offset 8 269
OutIn 3 16
End
Button 42
Type 1
Size 36 25
Offset 58 269
OutIn 5 16
End
Button 43
Type 1
Size 36 25
Offset 108 269
OutIn 5 8
End
Button 44
Type 1
Size 36 25
Offset 158 269
OutIn 5 4
End
Button 45
Type 1
Size 36 25
Offset 208 269
OutIn 5 2
End
Button 46
Type 1
Size 36 25
Offset 258 269
OutIn 5 1
End
Button 51
Type 1
Size 86 25
Offset 8 306
OutIn 4 16
End
Button 52
Type 1
Size 36 25
Offset 108 306
OutIn 4 8
End
Button 53
Type 1
Size 36 25
Offset 158 306
OutIn 4 4
End
Button 54
Type 1
Size 36 25
Offset 208 306
OutIn 4 2
End
Button 55
Type 1
Size 36 25
Offset 258 306
OutIn 4 1
End
Button 61
Type 1
Size 36 25
Offset 8 343
OutIn 3 32
End
Button 62
Type 1
Size 47 25
Offset 67 343
OutIn 3 8
End
Button 63
Type 1
Size 47 25
Offset 127 343
OutIn 3 4
End
Button 64
Type 1
Size 47 25
Offset 187 343
OutIn 3 2
End
Button 65
Type 1
Size 47 25
Offset 247 343
OutIn 3 1
End
Button 71
Type 1
Size 36 25
Offset 8 380
OutIn 2 32
End
Button 72
Type 1
Size 47 25
Offset 67 380
OutIn 2 8
End
Button 73
Type 1
Size 47 25
Offset 127 380
OutIn 2 4
End
Button 74
Type 1
Size 47 25
Offset 187 380
OutIn 2 2
End
Button 75
Type 1
Size 47 25
Offset 247 380
OutIn 2 1
End
Button 81
Type 1
Size 36 25
Offset 8 417
OutIn 1 32
End
Button 82
Type 1
Size 47 25
Offset 67 417
OutIn 1 8
End
Button 83
Type 1
Size 47 25
Offset 127 417
OutIn 1 4
End
Button 84
Type 1
Size 47 25
Offset 187 417
OutIn 1 2
End
Button 85
Type 1
Size 47 25
Offset 247 417
OutIn 1 1
End
Button 91
Type 1
Size 36 25
Offset 8 454
OutIn 0 32768
End
Button 92
Type 1
Size 47 25
Offset 67 454
OutIn 0 8
End
Button 93
Type 1
Size 47 25
Offset 127 454
OutIn 0 4
End
Button 94
Type 1
Size 47 25
Offset 187 454
OutIn 0 2
End
Button 95
Type 1
Size 47 25
Offset 247 454
OutIn 0 1
End
Include "Keyboard.kmi"

BIN
DEFAULTS.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

392
DEFAULTS.KML Normal file
View file

@ -0,0 +1,392 @@
Global
Title "Emu48's Default Faceplate for HP48S/SX"
Author "Sebastien Carlier"
Model "S"
Rom "ROM.48S"
Patch "BEEP.EXT"
Debug 0
Bitmap "DEFAULTS.BMP"
End
Background
Offset 0 0
Size 302 485
End
Lcd
Zoom 2
Offset 20 20
Color 0 255 255 255
Color 1 255 255 255
Color 2 255 255 255
Color 3 240 240 240
Color 4 225 225 225
Color 5 210 210 210
Color 6 195 195 195
Color 7 180 180 180
Color 8 165 165 165
Color 9 150 150 150
Color 10 135 135 135
Color 11 120 120 120
Color 12 105 105 105
Color 13 90 90 90
Color 14 75 75 75
Color 15 60 60 60
Color 16 45 45 45
Color 17 30 30 30
Color 18 15 15 15
Color 19 0 0 0
Color 20 0 0 0
Color 21 0 0 0
Color 22 0 0 0
Color 23 0 0 0
Color 24 0 0 0
Color 25 0 0 0
Color 26 0 0 0
Color 27 0 0 0
Color 28 0 0 0
Color 29 0 0 0
Color 30 0 0 0
Color 31 0 0 0
End
Annunciator 1
Size 15 11
Offset 41 4
Down 16 485
End
Annunciator 2
Size 15 11
Offset 82 4
Down 32 485
End
Annunciator 3
Size 13 11
Offset 123 4
Down 48 485
End
Annunciator 4
Size 15 11
Offset 164 4
Down 64 485
End
Annunciator 5
Size 11 11
Offset 205 4
Down 80 485
End
Annunciator 6
Size 12 11
Offset 246 4
Down 96 485
End
Button 11
Type 1
Size 36 25
Offset 8 158
OutIn 1 16
End
Button 12
Type 1
Size 36 25
Offset 58 158
OutIn 8 16
End
Button 13
Type 1
Size 36 25
Offset 108 158
OutIn 8 8
End
Button 14
Type 1
Size 36 25
Offset 158 158
OutIn 8 4
End
Button 15
Type 1
Size 36 25
Offset 208 158
OutIn 8 2
End
Button 16
Type 1
Size 36 25
Offset 258 158
OutIn 8 1
End
Button 21
Type 1
Size 36 25
Offset 8 195
OutIn 2 16
End
Button 22
Type 1
Size 36 25
Offset 58 195
OutIn 7 16
End
Button 23
Type 1
Size 36 25
Offset 108 195
OutIn 7 8
End
Button 24
Type 1
Size 36 25
Offset 158 195
OutIn 7 4
End
Button 25
Type 1
Size 36 25
Offset 208 195
OutIn 7 2
End
Button 26
Type 1
Size 36 25
Offset 258 195
OutIn 7 1
End
Button 31
Type 1
Size 36 25
Offset 8 232
OutIn 0 16
End
Button 32
Type 1
Size 36 25
Offset 58 232
OutIn 6 16
End
Button 33
Type 1
Size 36 25
Offset 108 232
OutIn 6 8
End
Button 34
Type 1
Size 36 25
Offset 158 232
OutIn 6 4
End
Button 35
Type 1
Size 36 25
Offset 208 232
OutIn 6 2
End
Button 36
Type 1
Size 36 25
Offset 258 232
OutIn 6 1
End
Button 41
Type 1
Size 36 25
Offset 8 269
OutIn 3 16
End
Button 42
Type 1
Size 36 25
Offset 58 269
OutIn 5 16
End
Button 43
Type 1
Size 36 25
Offset 108 269
OutIn 5 8
End
Button 44
Type 1
Size 36 25
Offset 158 269
OutIn 5 4
End
Button 45
Type 1
Size 36 25
Offset 208 269
OutIn 5 2
End
Button 46
Type 1
Size 36 25
Offset 258 269
OutIn 5 1
End
Button 51
Type 1
Size 86 25
Offset 8 306
OutIn 4 16
End
Button 52
Type 1
Size 36 25
Offset 108 306
OutIn 4 8
End
Button 53
Type 1
Size 36 25
Offset 158 306
OutIn 4 4
End
Button 54
Type 1
Size 36 25
Offset 208 306
OutIn 4 2
End
Button 55
Type 1
Size 36 25
Offset 258 306
OutIn 4 1
End
Button 61
Type 1
Size 36 25
Offset 8 343
OutIn 3 32
End
Button 62
Type 1
Size 47 25
Offset 67 343
OutIn 3 8
End
Button 63
Type 1
Size 47 25
Offset 127 343
OutIn 3 4
End
Button 64
Type 1
Size 47 25
Offset 187 343
OutIn 3 2
End
Button 65
Type 1
Size 47 25
Offset 247 343
OutIn 3 1
End
Button 71
Type 1
Size 36 25
Offset 8 380
OutIn 2 32
End
Button 72
Type 1
Size 47 25
Offset 67 380
OutIn 2 8
End
Button 73
Type 1
Size 47 25
Offset 127 380
OutIn 2 4
End
Button 74
Type 1
Size 47 25
Offset 187 380
OutIn 2 2
End
Button 75
Type 1
Size 47 25
Offset 247 380
OutIn 2 1
End
Button 81
Type 1
Size 36 25
Offset 8 417
OutIn 1 32
End
Button 82
Type 1
Size 47 25
Offset 67 417
OutIn 1 8
End
Button 83
Type 1
Size 47 25
Offset 127 417
OutIn 1 4
End
Button 84
Type 1
Size 47 25
Offset 187 417
OutIn 1 2
End
Button 85
Type 1
Size 47 25
Offset 247 417
OutIn 1 1
End
Button 91
Type 1
Size 36 25
Offset 8 454
OutIn 0 32768
End
Button 92
Type 1
Size 47 25
Offset 67 454
OutIn 0 8
End
Button 93
Type 1
Size 47 25
Offset 127 454
OutIn 0 4
End
Button 94
Type 1
Size 47 25
Offset 187 454
OutIn 0 2
End
Button 95
Type 1
Size 47 25
Offset 247 454
OutIn 0 1
End
Include "Keyboard.kmi"

BIN
EMU48.EXE Normal file

Binary file not shown.

View file

@ -1,7 +1,7 @@
Emu48 - A freeware HP48 Emulator for Windows 95 and NT Emu48 - A freeware HP48 Emulator for Windows 95, 98 and NT
@ -9,20 +9,16 @@
* INSTALLATION * * INSTALLATION *
**************** ****************
Emu48 is distributed in 3 separate archives : Emu48 is now distributed in a single archive, named Emu48-1.xx.zip. This version
- Emu48-1.x-bin.zip All the executables files (REQUIRED) integrates the changed made by Christoph Giesselink in his service pack 10.
- Emu48-1.x-src.zip The sources of Emu48 and some useful tools (OPTIONAL)
- Emu48-com.zip Files common to all 1.x versions (REQUIRES)
To install Emu48, just unzip Emu48-1.x-bin.zip and Emu48-com.zip into an empty To install Emu48, just unzip Emu48-1.xx.zip into an empty directory.
directory. When you first run Emu48, it will detect the directory in which you When you first run Emu48, it will detect the directory in which you
installed it, and will write its configuration to a file named Emu48.ini in installed it, and will write its configuration to a file named Emu48.ini in
your Windows directory. your Windows directory.
Note: Note:
As of version 1.0, Emu48 will only run with Windows 95 and NT. As of version 1.0, Emu48 will only run with Windows 95, 98 and NT.
I am working on a port to Unix (XWindow). When this is finished,
I may port it to Windows 3.1 and OS/2.
Since the source code is provided, you can add features or port it to new Since the source code is provided, you can add features or port it to new
plateforms, but you are required to send me your changes. plateforms, but you are required to send me your changes.
@ -39,7 +35,7 @@ To use the ROM software of a calculator, you must be the owner of this
calculator. calculator.
- If you have already used another HP48 emulator, you can convert the ROM with - If you have already used another HP48 emulator, you can convert the ROM with
you were using with the Conver utility. you were using with the Convert utility.
To do that, start a Command Promt while running Windows, and type : To do that, start a Command Promt while running Windows, and type :
Convert <old-file> ROM.48G Convert <old-file> ROM.48G
or Convert <old-file> ROM.48S or Convert <old-file> ROM.48S
@ -92,7 +88,7 @@ Click the refresh button ("V") after modifying it to update the list box.
Choose a KML script in the list box. If you have put a G/GX ROM dump in Emu48's Choose a KML script in the list box. If you have put a G/GX ROM dump in Emu48's
directory, choose a script for G/GX. If you have put a S/SX ROM dump in Emu48's directory, choose a script for G/GX. If you have put a S/SX ROM dump in Emu48's
directory, choose a script for S/SX. directory, choose a script for S/SX.
Several scripts are included in the common archive : Several scripts are included in the archive :
* Emu48's Default Faceplate for HP48G/GX * Emu48's Default Faceplate for HP48G/GX
* Emu48's Default Faceplate for HP48S/SX * Emu48's Default Faceplate for HP48S/SX
These two are simple scripts, and they use the bitmap from Win48 2.05. These two are simple scripts, and they use the bitmap from Win48 2.05.
@ -189,7 +185,11 @@ I cannot provide individual support for Emu48, but I will read all the mails
that you send. that you send.
All informations about Emu48 will be on the Emu48 Official Homepage on the Web : All informations about Emu48 will be on the Emu48 Official Homepage on the Web :
http://www.geocities.com/CapeCanaveral/5948/index.html http://www.epita.fr/~sebc/Emu48
Service packs are maintained by Christoph Gießelink :
http://privat.swol.de/ChristophGiesselink/
Other graphics and scripts are available at Casey's Emu48 Graphics Page : Other graphics and scripts are available at Casey's Emu48 Graphics Page :
http://www.gulftel.com/~pattersc/emu48/ http://www.gulftel.com/~pattersc/emu48/
@ -231,7 +231,6 @@ Paper Mail:
E-Mail: E-Mail:
sebc@epita.fr sebc@epita.fr
sebc@anet.fr
Homepage: Homepage:
http://www.geocities.com/CapeCanaveral/5948/index.html http://www.epita.fr/~sebc

137
EMU48SP.TXT Normal file
View file

@ -0,0 +1,137 @@
Emu48 - A freeware HP48 Emulator for Windows 95 and NT
--- Changes and Additions of Emu48 V1.0 ---
Thank Sebastien Carlier for his emulator and that he made the sources public. Special thanks to Jean-Yves Avenard, Cyrille de Brebisson and Will Laughin for there suggestions, additions and fixes.
My first contact with this emulator (Shareware Win48) was in early 1997. At this time I worked with Windows NT 4.0. The emulator was unusable for me at this time. As well I had some problems with the latest version of Emu48 (Version 1.0). This was the beginning of the "Unofficial Service Packs".
********************
* OPERATING SYSTEM *
********************
This version of Emu48 should work with all Intel Win32 platforms. Several problems with Windows NT 4.0, Win95b and Win98 are fixed now. You may recompile the sources to run Emu48 on a DEC Alpha.
****************
* COMMAND LINE *
****************
The command line syntax is "Emu48 [E48file [Port2file]]". The first parameter sets the filename for the Emulation Data, the second parameter the Port2 file. You're not able to set a Port2 file without setting the Emulation Data file. The arguments are optional.
***********
* DISPLAY *
***********
The display emulation is now closer to the original. But there are several problems left, especially with the gray scale emulation.
********************
* KEYBOARD CHANGES *
********************
I changed the behavior for pressing more than one key. All keys will release, when you go outside the button area now. To hold down a key, you have to press the right mouse button. The key autorepeat emulation is working now.
*********
* CLOCK *
*********
The emulator time is synchronized with the PC time at startup of the emulator. This may cause problems with other non original operating systems running on the HP48. On S(X) calculators the address area #00052-#00070, on G(X) calculators the address area #00058-#00076 in Port0 are rewritten with the actual time information.
***************
* KML SCRIPTS *
***************
Your LCD contrast setting will be saved now. In some cases you have to fix Color 0 in your KML script file, because the colors red and blue has been swapped in the "Lcd" section. Don't use TRUELCD.KMI for emulating display contrast in your scripts. It's not fully correct. The hardware contrast values are in the area from 0 to 31. But the HP48 roms bounds them to useful values. The S(X) ROM use only display contrast values between 3 and 19 and the G(X) ROM values between 9 and 24.
You're able to define a different background color for each contrast value for a more realistic display emulation now. The background color entry for the corresponding color is calculated by adding 32 to the color value. That means the color definitions from 32 to 63 are background colors. If the background color for the contrast isn't defined, Color 0 is used.
You can use 4 as new value for "Zoom" in the "Lcd" section of the KML script for a very big display view now.
***********************
* COPY / PASTE STRING *
***********************
With the menu items "Copy String" and "Paste String" in the "Edit" menu you're able to copy HP48 string objects from the stack to the PC Clipboard and vice versa.
*****************
* DRAG AND DROP *
*****************
Dropping HP48 objects over the emulator window will load program files (like the command "Load object...") on the stack. Be sure that the emulator isn't busy before doing this.
*************
* EMU48.INI *
*************
The section [Timers] in the Emu48.ini file isn't used any more. The variable values are replaced by useful constants. You may delete this section if you want. Starting an old version of Emu48 (V1.07 and earlier) will add this section again.
************************
* REAL SPEED EMULATION *
************************
As you recognized the speed of the emulated HP48 is much faster than an original HP48. The reason is, the assembler commands are emulated faster than the original CPU can execute them. On one side this is a big advantage (faster execution of programs) on the other side this cause many trouble. In Emu48 only the timers work with the original speed. In result all commands like User-RPL WAIT wait more or less the correct time. But many programs like shells or editors use an own key handler to realize an autorepeat implementation. Normally these programs use the execution time of each assembler command for waiting. On Emu48 this time is much shorter, so the time between each key read is shorter as well and you get a very fast key repetition. The editor ED from the JAZZ package hasn't this problem, because the key input is synchronized with one of the timers. To solve this problem Emu48 generally slow down emulation if a key is pressed. To solve some other speed depending problems you are able to slow down the whole emulation speed. There are two variables 'SXCycles=82' and 'GXCycles=123' defined in the Emu48.ini file, section [Emulator] which control the "real" speed and key repetition slow down for each calculator type. Each numeric value is representing the allowed CPU cycles in a 16384Hz time frame. Because the used cycle statements (from SASM.DOC) in Emu48 doesn't correspond to the real values of the CPU, the saved values are estimated by comparing the execution time of a program to the real calculator. Increasing the value fitting to your ROM will make the "real speed" HP faster and vice versa. No warranty to the functionality of Emu48 when you go below the default values.
*************************
* SERIAL PORT EMULATION *
*************************
The serial ports are emulated as well now. You may choose the same serial port for wire and IR. Remember that the IR port only work with 2400 Baud. There's a problem known with the command RECX from the Library 1275: "XYMODEM v3.2 for S/G". On fast PC's this command doesn't work. Slow down emulation to run it. If you want to change the serial port settings, but they are disabled, close the serial port with the command CLOSEIO or power cycle the HP48 first.
Now it's possible to make transfers between the HP48 and Emu48. If you have problems with the connection please try the following. There's a simple way to check if your serial port is used by another program. First disable the serial settings in both combo boxes and very important close the settings dialog. Reopen the settings dialog and choose the COM port in the wire combo box to the port the HP48 is connected with. When you open this combo box you only see valid (unused) serial ports. Don't use the IR combo box, it only works with 2400 Baud. The next important thing are the serial settings of the HP48 and Emu48, they must be equal. If this doesn't work then mostly there's a hardware problem, check this with connecting the HP48 with a transfer program you like on the same serial port.
****************
* DISASSEMBLER *
****************
With the internal disassembler you're able to disassemble the HP48 address area. With the default Map setting the disassembler always see the mapped memory address. If for example you configured the RAM at #00000 you will see the RAM and not the ROM at this address. With the other Module settings you specify a special module for disassembly. Each module will begin at address #00000 and will not overlapped by other modules. For Port2 I use a linear address mode, that means that the second port of a RAM card greater than 128K is at address #40000 (128 * 1024 * 2) and so on. The "Copy Data" button copies the selected disassembler lines to the PC Clipboard.
**************
* DDE SERVER *
**************
I implemented a DDE server in Emu48 to transmit data from and to the HP stack with DDE. You have the same restrictions like with the commands "Load object..." and "Save Object...", that a running program may corrupt memory. Take care to transmit data only after the acknowledge of the last DDE transaction.
Technical data:
Servername: Emu48
Topicname: Stack
Item: Dummy (ignored, must be a nonzero string)
Clipboardformat: "CF_HPOBJ" (user defined)
The DDE commands CONNECT, POKE and REQUEST are supported.
The structure of the clipboard format "CF_HPOBJ":
+--------+------------------------------------+
| 4 Byte | HP object |
+--------+------------------------------------+
\ \
\ +--- normal HP object
+----------- length of object (LSB first)
********
* TIPS *
********
I hope some of your Emu48 problems has been solved as well. If you use a patched ROM version (i.e. to solve the auto off problem), try an unpatched one.
Christoph Gießelink, cgiess@swol.de
http://privat.swol.de/ChristophGiesselink

Binary file not shown.

View file

@ -1,979 +0,0 @@
/*
* Emu48.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
#include "kml.h"
#define VERSION "1.0"
#define EMU48_INI "Emu48.ini"
#ifdef _DEBUG
LPSTR szNoTitle = "Emu48 "VERSION" Debug";
#else
LPSTR szNoTitle;
#endif
LPSTR szTitle = NULL;
static const char szLicence[] =
"This program is free software; you can redistribute it and/or modify\r\n"
"it under the terms of the GNU General Public License as published by\r\n"
"the Free Software Foundation; either version 2 of the License, or\r\n"
"(at your option) any later version.\r\n"
"\r\n"
"This program is distributed in the hope that it will be useful,\r\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n"
"See the GNU General Public License for more details.\r\n"
"\r\n"
"You should have received a copy of the GNU General Public License\r\n"
"along with this program; if not, write to the Free Software\r\n"
"Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.";
HINSTANCE hApp = NULL;
HWND hWnd = NULL;
HDC hWindowDC = NULL;
HPALETTE hPalette = NULL;
HANDLE hThread;
DWORD lThreadId;
BOOL bAutoSave = FALSE;
BOOL bAutoSaveOnExit = TRUE;
BOOL bAlwaysDisplayLog = TRUE;
//################
//#
//# Window Status
//#
//################
VOID SetWindowTitle(LPSTR szString)
{
if (szTitle)
{
LocalFree(szTitle);
}
if (szString)
{
szTitle = DuplicateString(szString);
}
else
{
szTitle = NULL;
}
if (szTitle)
{
SetWindowText(hWnd, szTitle);
}
else
{
SetWindowText(hWnd, szNoTitle);
}
return;
}
VOID UpdateWindowStatus()
{
HMENU hMenu;
hMenu = GetMenu(hWnd);
if ((nState == 0)||(nState == 3))
{
if (szCurrentFilename[0])
EnableMenuItem(hMenu,ID_FILE_SAVE,MF_ENABLED);
else
EnableMenuItem(hMenu,ID_FILE_SAVE,MF_GRAYED);
EnableMenuItem(hMenu,ID_FILE_SAVEAS,MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_CLOSE,MF_ENABLED);
EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_GRAYED);
EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_ENABLED);
EnableMenuItem(hMenu,ID_VIEW_COPY,MF_ENABLED);
EnableMenuItem(hMenu,ID_VIEW_RESET,MF_ENABLED);
EnableMenuItem(hMenu,ID_OBJECT_LOAD,MF_ENABLED);
EnableMenuItem(hMenu,ID_OBJECT_SAVE,MF_ENABLED);
}
else
{
EnableMenuItem(hMenu,ID_FILE_SAVE,MF_GRAYED);
EnableMenuItem(hMenu,ID_FILE_SAVEAS,MF_GRAYED);
EnableMenuItem(hMenu,ID_FILE_CLOSE,MF_ENABLED);
EnableMenuItem(hMenu,ID_BACKUP_SAVE,MF_GRAYED);
EnableMenuItem(hMenu,ID_VIEW_COPY,MF_GRAYED);
EnableMenuItem(hMenu,ID_VIEW_RESET,MF_GRAYED);
EnableMenuItem(hMenu,ID_OBJECT_LOAD,MF_GRAYED);
EnableMenuItem(hMenu,ID_OBJECT_SAVE,MF_GRAYED);
}
if (bBackup)
{
EnableMenuItem(hMenu,ID_BACKUP_RESTORE,MF_ENABLED);
EnableMenuItem(hMenu,ID_BACKUP_DELETE,MF_ENABLED);
}
else
{
EnableMenuItem(hMenu,ID_BACKUP_RESTORE,MF_GRAYED);
EnableMenuItem(hMenu,ID_BACKUP_DELETE,MF_GRAYED);
}
return;
}
//################
//#
//# Settings
//#
//################
static BOOL WritePrivateProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nValue, LPCTSTR lpszFilename)
{
char s[16];
wsprintf(s,"%i",nValue);
return WritePrivateProfileString(lpszSection, lpszEntry, s, lpszFilename);
}
static VOID ReadSettings()
{
// Files
GetPrivateProfileString("Files","Emu48Directory",szCurrentDirectory,szEmu48Directory,260,EMU48_INI);
bAutoSave = GetPrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI);
bAutoSaveOnExit = GetPrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI);
// Port2
bPort2IsShared = GetPrivateProfileInt("Port2","IsShared",0,EMU48_INI);
GetPrivateProfileString("Port2","Filename","SHARED.BIN",szPort2Filename,260,EMU48_INI);
// Timers
bAccurateTimer = GetPrivateProfileInt("Timers","AccurateTimer",0,EMU48_INI);
uT1Period = GetPrivateProfileInt("Timers","T1Period",62,EMU48_INI);
// KML
bAlwaysDisplayLog = GetPrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI);
return;
}
static VOID WriteSettings()
{
// Files
WritePrivateProfileString("Files","Emu48Directory",szEmu48Directory,EMU48_INI);
WritePrivateProfileInt("Files","AutoSave",bAutoSave,EMU48_INI);
WritePrivateProfileInt("Files","AutoSaveOnExit",bAutoSaveOnExit,EMU48_INI);
// Port2
WritePrivateProfileInt("Port2","IsShared",bPort2IsShared,EMU48_INI);
WritePrivateProfileString("Port2","Filename",szPort2Filename,EMU48_INI);
// Timers
WritePrivateProfileInt("Timers","AccurateTimer",bAccurateTimer,EMU48_INI);
WritePrivateProfileInt("Timers","T1Period",uT1Period,EMU48_INI);
// KML
WritePrivateProfileInt("KML","AlwaysDisplayLog",bAlwaysDisplayLog,EMU48_INI);
return;
}
static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
CheckDlgButton(hDlg,IDC_PORT1WR,Chipset.Port1_Writeable);
CheckDlgButton(hDlg,IDC_AUTOSAVE,bAutoSave);
CheckDlgButton(hDlg,IDC_AUTOSAVEONEXIT,bAutoSaveOnExit);
CheckDlgButton(hDlg,IDC_ALWAYSDISPLOG,bAlwaysDisplayLog);
CheckDlgButton(hDlg,IDC_PORT2ISSHARED,bPort2IsShared);
SetDlgItemText(hDlg,IDC_PORT2,szPort2Filename);
SetDlgItemInt(hDlg,IDC_T1PERIOD,uT1Period,FALSE);
CheckDlgButton(hDlg,IDC_USEMMTIMER,bAccurateTimer);
if (nState == 1)
{
EnableWindow(GetDlgItem(hDlg,IDC_PORT1WR),FALSE);
}
else
{
EnableWindow(GetDlgItem(hDlg,IDC_PORT2ISSHARED),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE);
}
return TRUE;
case WM_COMMAND:
if (wParam == IDOK)
{
BOOL bTranslated;
UINT uNewT1Period;
if (Chipset.Port1Size)
{
UINT nOldState = SwitchToState(3);
Chipset.Port1_Writeable = IsDlgButtonChecked(hDlg, IDC_PORT1WR);
if (cCurrentRomType=='S')
{
Chipset.cards_status = (Chipset.Port1_Writeable)?0x5:0x1;
if (Chipset.inte)
{
Chipset.Shutdn = FALSE;
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
Map(0x00,0xFF);
}
else
{
Chipset.cards_status = (Chipset.Port1_Writeable)?0xA:0x2;
if (Chipset.inte)
{
Chipset.Shutdn = FALSE;
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
Map(0x00,0xFF);
}
SwitchToState(nOldState);
}
bAutoSave = IsDlgButtonChecked(hDlg, IDC_AUTOSAVE);
bAutoSaveOnExit = IsDlgButtonChecked(hDlg, IDC_AUTOSAVEONEXIT);
bAlwaysDisplayLog = IsDlgButtonChecked(hDlg, IDC_ALWAYSDISPLOG);
if (nState == 1)
{
bPort2IsShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED);
GetDlgItemText(hDlg,IDC_PORT2,szPort2Filename,260);
}
bAccurateTimer = IsDlgButtonChecked(hDlg,IDC_USEMMTIMER);
uNewT1Period = GetDlgItemInt(hDlg, IDC_T1PERIOD, &bTranslated, FALSE);
if (bTranslated)
uT1Period = uNewT1Period;
else
uT1Period = 62;
EndDialog(hDlg, wParam);
}
if (wParam == IDCANCEL)
{
EndDialog(hDlg, wParam);
}
if (wParam == IDC_T1DEFAULT)
{
SetDlgItemInt(hDlg,IDC_T1PERIOD,62,FALSE);
}
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(hDlg);
}
//################
//#
//# Save Helper
//#
//################
//
// UINT SaveChanges(BOOL bAuto);
// Return code :
// IDYES File successfuly saved
// IDNO File not saved
// IDCANCEL Cancel command
//
static UINT SaveChanges(BOOL bAuto)
{
UINT uReply;
if (pbyRom == NULL) return IDNO;
if (bAuto)
uReply = IDYES;
else
uReply = YesNoCancelMessage("Do you want to save changes ?");
if (uReply != IDYES) return uReply;
if (szCurrentFilename[0]==0)
{ // Save As...
uReply = GetSaveAsFilename();
if (uReply != IDOK) return uReply;
if (!SaveDocumentAs(szBufferFilename)) return IDCANCEL;
WritePrivateProfileString("Files","LastDocument",szCurrentFilename,EMU48_INI);
return IDYES;
}
SaveDocument();
return IDYES;
}
//################
//#
//# Message Handlers
//#
//################
//
// WM_CREATE
//
static LRESULT OnCreate(HWND hWindow)
{
hWnd = hWindow;
hWindowDC = GetDC(hWnd);
return 0;
}
//
// WM_DESTROY
//
static LRESULT OnDestroy(HWND hWindow)
{
SwitchToState(2);
WriteSettings();
ReleaseDC(hWnd, hWindowDC);
hWnd = NULL;
PostQuitMessage(0);
return 0;
UNREFERENCED_PARAMETER(hWindow);
}
//
// WM_PAINT
//
static LRESULT OnPaint(HWND hWindow)
{
PAINTSTRUCT Paint;
HDC hPaintDC;
hPaintDC = BeginPaint(hWindow, &Paint);
if (hMainDC == NULL) return 0;
if ((nState==0)||(nState==3))
{
BitBlt(hPaintDC, 0, 0, nBackgroundW, nBackgroundH, hMainDC, nBackgroundX, nBackgroundY, SRCCOPY);
UpdateMainDisplay();
UpdateMenuDisplay();
RefreshButtons();
}
else
{
BitBlt(hPaintDC, 0, 0, nBackgroundW, nBackgroundH, hMainDC, nBackgroundX, nBackgroundY, SRCCOPY);
}
EndPaint(hWindow, &Paint);
return 0;
}
//
// ID_FILE_NEW
//
static LRESULT OnFileNew()
{
UINT uReply;
SaveBackup();
if (pbyRom)
{
SwitchToState(1);
uReply = SaveChanges(bAutoSave);
if (uReply==IDCANCEL) goto cancel;
}
NewDocument();
SetWindowTitle("Untitled");
UpdateWindowStatus();
cancel:
if (pbyRom) SwitchToState(0);
return 0;
}
//
// ID_FILE_OPEN
//
static LRESULT OnFileOpen()
{
UINT uReply;
if (pbyRom)
{
SwitchToState(1);
uReply = SaveChanges(bAutoSave);
if (uReply==IDCANCEL) goto cancel;
}
if (GetOpenFilename())
{
OpenDocument(szBufferFilename);
}
cancel:
if (pbyRom)
{
SwitchToState(0);
}
return 0;
}
//
// ID_FILE_SAVE
//
static LRESULT OnFileSave()
{
if (pbyRom == NULL) return 0;
SwitchToState(1);
SaveChanges(TRUE);
SwitchToState(0);
return 0;
}
//
// ID_FILE_SAVEAS
//
static LRESULT OnFileSaveAs()
{
UINT uReply;
if (pbyRom == NULL) return 0;
SwitchToState(1);
uReply = GetSaveAsFilename();
if (uReply != IDOK)
{
SwitchToState(0);
return 0;
}
if (!SaveDocumentAs(szBufferFilename))
{
SwitchToState(0);
return 0;
}
WritePrivateProfileString("Files","LastDocument",szCurrentFilename,EMU48_INI);
SwitchToState(0);
return 0;
}
//
// ID_FILE_CLOSE
//
static LRESULT OnFileClose()
{
if (pbyRom == NULL) return 0;
SwitchToState(1);
if (SaveChanges(bAutoSave)!=IDCANCEL)
{
KillKML();
ResetDocument();
SetWindowTitle(NULL);
}
else
{
SwitchToState(0);
}
return 0;
}
//
// ID_FILE_EXIT
//
static LRESULT OnFileExit()
{
if (SaveChanges(bAutoSaveOnExit) == IDCANCEL)
{
return 0;
}
DestroyWindow(hWnd);
return 0;
}
//
// WM_SYS_CLOSE
//
static LRESULT OnSysClose()
{
if (SaveChanges(bAutoSaveOnExit) == IDCANCEL)
{
return 0;
}
DestroyWindow(hWnd);
return 0;
}
//
// ID_VIEW_COPY
//
static LRESULT OnViewCopy()
{
HBITMAP hOldBmp, hBmp;
HDC hBmpDC;
if (!OpenClipboard(hWnd)) return 0;
if (!EmptyClipboard()) return 0;
if (bLcdDoubled)
{
hBmp = CreateBitmap(262,128,1,1,NULL);
hBmpDC = CreateCompatibleDC(NULL);
hOldBmp = (HBITMAP)SelectObject(hBmpDC,hBmp);
BitBlt(hBmpDC, 0, 0, 262, 128, hLcdDC, 0, 0, SRCCOPY);
}
else
{
hBmp = CreateBitmap(131,64,1,1,NULL);
hBmpDC = CreateCompatibleDC(NULL);
hOldBmp = (HBITMAP)SelectObject(hBmpDC,hBmp);
BitBlt(hBmpDC, 0, 0, 131, 64, hLcdDC, 0, 0, SRCCOPY);
}
SetClipboardData(CF_BITMAP,hBmp);
SelectObject(hBmpDC,hOldBmp);
DeleteDC(hBmpDC);
CloseClipboard();
return 0;
}
//
// ID_VIEW_RESET
//
static LRESULT OnViewReset()
{
if (nState!=0) return 0;
if (YesNoMessage("Are you sure you want to press the Reset Button ?")==IDYES)
{
SwitchToState(3);
Chipset.pc = 0;
Chipset.inte = TRUE;
Chipset.Shutdn = FALSE;
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
SwitchToState(0);
}
return 0;
}
//
// ID_VIEW_SETTINGS
//
static LRESULT OnViewSettings()
{
ReadSettings();
if (nState == 1) UnmapPort2();
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_SETTINGS), hWnd, (DLGPROC)SettingsProc) == -1)
AbortMessage("Settings Dialog Creation Error !");
if (nState == 1) MapPort2(szPort2Filename);
WriteSettings();
return 0;
}
//
// ID_VIEW_SCRIPT
//
static LRESULT OnViewScript()
{
CHAR cType = cCurrentRomType;
if (nState!=0)
{
InfoMessage("You cannot change the KML script when Emu48 is not running.\n"
"Use the File,New menu item to create a new calculator.");
return 0;
}
SwitchToState(1);
retry:
if (!DisplayChooseKml(cType)) goto ok;
if (!InitKML(szCurrentKml,FALSE))
{
if (AbortMessage("This KML Script has errors.\nPress Ok to try to find a correct script.")==IDCANCEL)
{
if (szCurrentFilename[0])
OnFileSave();
else
OnFileSaveAs();
goto ok;
}
goto retry;
}
ok:
if (pbyRom) SwitchToState(0);
return 0;
}
//
// ID_BACKUP_SAVE
//
static LRESULT OnBackupSave()
{
UINT nOldState;
if (pbyRom == NULL) return 0;
nOldState = SwitchToState(1);
SaveBackup();
SwitchToState(nOldState);
return 0;
}
//
// ID_BACKUP_RESTORE
//
static LRESULT OnBackupRestore()
{
SwitchToState(1);
RestoreBackup();
if (pbyRom) SwitchToState(0);
return 0;
}
//
// ID_BACKUP_DELETE
//
static LRESULT OnBackupDelete()
{
ResetBackup();
return 0;
}
//
// ID_OBJECT_LOAD
//
static LRESULT OnObjectLoad()
{
static BOOL bWarning = TRUE;
if (nState!=0)
{
InfoMessage("The emulator must be running to load an object.");
return 0;
}
SwitchToState(3);
if (bWarning)
{
UINT uReply = YesNoCancelMessage(
"Warning: Trying to load an object while the emulator is busy \n"
"will certainly result in a memory lost. Before loading an object \n"
"you should be sure that the HP48 is not doing anything. \n"
"Do you want to see this warning next time you try to load an object ?");
switch (uReply)
{
case IDYES:
break;
case IDNO:
bWarning = FALSE;
break;
case IDCANCEL:
SwitchToState(0);
return 0;
}
}
if (!GetLoadObjectFilename())
{
SwitchToState(0);
return 0;
}
if (!LoadObject(szBufferFilename))
{
SwitchToState(0);
return 0;
}
SwitchToState(0);
while (nState!=nNextState) Sleep(0);
KeyboardEvent(TRUE,0,0x8000);
Sleep(200);
KeyboardEvent(FALSE,0,0x8000);
Sleep(100);
KeyboardEvent(TRUE,0,0x8000);
Sleep(200);
KeyboardEvent(FALSE,0,0x8000);
return 0;
}
//
// ID_OBJECT_SAVE
//
static LRESULT OnObjectSave()
{
if (nState!=0)
{
InfoMessage("The emulator must be running to save an object.");
return 0;
}
SwitchToState(3);
if (!GetSaveObjectFilename())
{
SwitchToState(0);
return 0;
}
SaveObject(szBufferFilename);
SwitchToState(0);
return 0;
}
//
// ID_ABOUT
//
static BOOL CALLBACK About(HWND hDlg, UINT message, DWORD wParam, LONG lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,IDC_VERSION,szNoTitle);
SetDlgItemText(hDlg,IDC_LICENSE,szLicence);
return TRUE;
case WM_COMMAND:
if ((wParam==IDOK)||(wParam==IDCANCEL))
{
EndDialog(hDlg, wParam);
break;
}
break;
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(hDlg);
}
static LRESULT OnAbout()
{
if (pbyRom) SwitchToState(3);
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1)
AbortMessage("About Dialog Box Creation Error !");
if (pbyRom) SwitchToState(0);
return 0;
}
static LRESULT OnLButtonDown(UINT nFlags, WORD x, WORD y)
{
if (nState==0) MouseButtonDownAt(nFlags, x,y);
return 0;
}
static LRESULT OnLButtonUp(UINT nFlags, WORD x, WORD y)
{
if (nState==0) MouseButtonUpAt(nFlags, x,y);
return 0;
}
static LRESULT OnMouseMove(UINT nFlags, WORD x, WORD y)
{
if (nState==0) MouseMovesTo(nFlags, x,y);
return 0;
}
static LRESULT OnKeyDown(int nVirtKey, DWORD lKeyData)
{
if (nState==0) RunKey((BYTE)nVirtKey, TRUE);
return 0;
UNREFERENCED_PARAMETER(lKeyData);
}
static LRESULT OnKeyUp(int nVirtKey, DWORD lKeyData)
{
if (nState==0) RunKey((BYTE)nVirtKey, FALSE);
return 0;
UNREFERENCED_PARAMETER(lKeyData);
}
static LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE: return OnCreate(hWindow);
case WM_DESTROY: return OnDestroy(hWindow);
case WM_PAINT: return OnPaint(hWindow);
case WM_ACTIVATE:
if (LOWORD(wParam)==WA_INACTIVE) break;
case WM_QUERYNEWPALETTE:
if (hPalette)
{
SelectPalette(hWindowDC, hPalette, FALSE);
if (RealizePalette(hWindowDC))
{
InvalidateRect(hWindow,NULL,TRUE);
return TRUE;
}
}
return FALSE;
case WM_PALETTECHANGED:
if ((HWND)wParam == hWindow) break;
if (hPalette)
{
SelectPalette(hWindowDC, hPalette, FALSE);
if (RealizePalette(hWindowDC))
{
// UpdateColors(hWindowDC);
InvalidateRect (hWnd, (LPRECT) (NULL), 1);
}
}
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_FILE_NEW: return OnFileNew();
case ID_FILE_OPEN: return OnFileOpen();
case ID_FILE_SAVE: return OnFileSave();
case ID_FILE_SAVEAS: return OnFileSaveAs();
case ID_FILE_CLOSE: return OnFileClose();
case ID_FILE_EXIT: return OnFileExit();
case ID_VIEW_COPY: return OnViewCopy();
case ID_VIEW_RESET: return OnViewReset();
case ID_VIEW_SETTINGS: return OnViewSettings();
case ID_VIEW_SCRIPT: return OnViewScript();
case ID_BACKUP_SAVE: return OnBackupSave();
case ID_BACKUP_RESTORE:return OnBackupRestore();
case ID_BACKUP_DELETE: return OnBackupDelete();
case ID_OBJECT_LOAD: return OnObjectLoad();
case ID_OBJECT_SAVE: return OnObjectSave();
case ID_ABOUT: return OnAbout();
}
break;
case WM_SYSCOMMAND:
switch (LOWORD(wParam))
{
case SC_CLOSE: return OnSysClose();
}
break;
case WM_LBUTTONDOWN: return OnLButtonDown(wParam, LOWORD(lParam), HIWORD(lParam));
case WM_LBUTTONUP: return OnLButtonUp(wParam, LOWORD(lParam), HIWORD(lParam));
case WM_MOUSEMOVE: return OnMouseMove(wParam, LOWORD(lParam), HIWORD(lParam));
case WM_KEYUP: return OnKeyUp((int)wParam, lParam);
case WM_KEYDOWN: return OnKeyDown((int)wParam, lParam);
}
return DefWindowProc(hWindow, uMsg, wParam, lParam);
}
static BOOL FlushMessages(LPMSG msg)
{
while (PeekMessage(msg, NULL, 0, 0, PM_REMOVE))
{
if (msg->message == WM_QUIT) return TRUE;
TranslateMessage(msg);
DispatchMessage(msg);
}
return FALSE;
}
int PASCAL WinMain(HANDLE hInst, HANDLE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
WNDCLASS wc;
RECT rectWindow;
hApp = hInst;
wc.style = CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_EMU48));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = "CEmu48";
if (!RegisterClass(&wc))
{
AbortMessage(
"CEmu48 class registration failed.\n"
"This application will now terminate.");
return FALSE;
}
// Create window
rectWindow.left = 0;
rectWindow.top = 0;
rectWindow.right = 256;
rectWindow.bottom = 0;
AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
hWnd = CreateWindow("CEmu48", "Emu48",
WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
NULL,NULL,hApp,NULL
);
if (hWnd == NULL)
{
AbortMessage("Window creation failed.\n");
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
if (FlushMessages(&msg)) return msg.wParam;
// initialization
GetCurrentDirectory(260, szCurrentDirectory);
ReadSettings();
szNoTitle = "Emu48 "VERSION;
UpdateWindowStatus();
nState = 1; // thread starts in an invalid state
nNextState = 1;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&WorkerThread, NULL, 0, &lThreadId);
if (hThread == NULL)
{
AbortMessage("Thread creation failed.");
return FALSE;
}
MapPort2(szPort2Filename);
if (lpCmdLine[0])
{
CHAR szTemp[256] = "Loading ";
strcat(szTemp, lpCmdLine);
SetWindowTitle(szTemp);
if (FlushMessages(&msg)) return msg.wParam;
if (OpenDocument(lpCmdLine))
goto start;
}
GetPrivateProfileString("Files","LastDocument",NULL,szBufferFilename,260,EMU48_INI);
if (szBufferFilename[0])
{
CHAR szTemp[256] = "Loading ";
strcat(szTemp, szBufferFilename);
SetWindowTitle(szTemp);
if (FlushMessages(&msg)) return msg.wParam;
if (OpenDocument(szBufferFilename))
goto start;
}
SetWindowTitle("New Document");
if (FlushMessages(&msg)) return msg.wParam;
if (NewDocument())
{
SetWindowTitle("Untitled");
goto start;
}
ResetDocument();
SetWindowTitle(NULL);
start:
if (pbyRom) SwitchToState(0);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SwitchToState(2);
ResetDocument();
ResetBackup();
cCurrentRomType = 0;
KillKML();
UnmapPort2();
return msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(hPrevInst);
}

View file

@ -1,159 +0,0 @@
/*
* Emu48.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "types.h"
// Emu48.c
extern HPALETTE hPalette;
extern LPSTR szTitle;
extern HANDLE hApp;
extern HWND hWnd;
extern HDC hWindowDC;
extern BOOL bPort2IsShared;
extern BOOL bAlwaysDisplayLog;
extern UINT uTimer1Period;
extern VOID SetWindowTitle(LPSTR szString);
extern VOID UpdateWindowStatus();
// Display.c
extern UINT nBackgroundX;
extern UINT nBackgroundY;
extern UINT nBackgroundW;
extern UINT nBackgroundH;
extern UINT nLcdX;
extern UINT nLcdY;
extern BOOL bLcdDoubled;
extern LPBYTE pbyLcd;
extern HDC hLcdDC;
extern HDC hMainDC;
extern VOID UpdateContrast(BYTE byContrast);
extern VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue);
extern VOID CreateLcdBitmap();
extern VOID DestroyLcdBitmap();
extern BOOL CreateMainBitmap(LPSTR szFilename);
extern VOID DestroyMainBitmap();
extern VOID UpdateDisplayPointers();
extern VOID UpdateMainDisplay();
extern VOID UpdateMenuDisplay();
extern VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID UpdateAnnunciators();
extern VOID ResizeWindow();
// Engine.c
extern BOOL bInterrupt;
extern UINT nState;
extern UINT nNextState;
extern HANDLE hThread;
extern CHIPSET Chipset;
extern UINT SwitchToState(UINT nNewState);
extern UINT WorkerThread(LPVOID pParam);
extern DWORD Npack(BYTE *a, UINT s);
extern VOID Nunpack(BYTE *a, DWORD b, UINT s);
// Files.c
extern char szEmu48Directory[260];
extern char szCurrentDirectory[260];
extern char szCurrentKml[260];
extern char szBackupKml[260];
extern char szCurrentFilename[260];
extern char szBackupFilename[260];
extern char szBufferFilename[260];
extern char szPort2Filename[260];
extern LPBYTE pbyRom;
extern DWORD dwRomSize;
extern char cCurrentRomType;
extern LPBYTE pbyPort2;
extern BOOL bPort2Writeable;
extern BOOL bPort2IsShared;
extern DWORD dwPort2Mask;
extern UINT nPort2Bank;
extern BOOL bBackup;
extern BOOL MapRom(LPCSTR szFilename);
extern VOID UnmapRom();
extern BOOL MapPort2(LPCSTR szFilename);
extern VOID UnmapPort2();
extern BOOL PatchRom(LPCSTR szFilename);
extern VOID ResetDocument();
extern BOOL NewDocument();
extern BOOL OpenDocument(LPCSTR szFilename);
extern BOOL SaveDocument();
extern BOOL SaveDocumentAs(LPCTSTR szFilename);
extern BOOL SaveBackup();
extern BOOL RestoreBackup();
extern BOOL ResetBackup();
extern BOOL GetOpenFilename();
extern BOOL GetSaveAsFilename();
extern BOOL GetLoadObjectFilename();
extern BOOL GetSaveObjectFilename();
extern BOOL LoadObject(LPCSTR szFilename);
extern BOOL SaveObject(LPCSTR szFilename);
extern HBITMAP LoadBitmapFile(LPCSTR szFilename);
// Timer.c
extern BOOL bAccurateTimer;
extern UINT uT1Period;
extern VOID StartTimers();
extern VOID StopTimers();
extern DWORD ReadT2();
extern VOID SetT2(DWORD dwValue);
extern BYTE ReadT1();
extern VOID SetT1(BYTE byValue);
// MOps.c
extern LPBYTE RMap[256];
extern LPBYTE WMap[256];
extern VOID Map(BYTE a, BYTE b);
extern VOID Config();
extern VOID Uncnfg();
extern VOID Reset();
extern VOID C_Eq_Id();
extern VOID Npeek(BYTE *a, DWORD d, UINT s);
extern VOID Nread(BYTE *a, DWORD d, UINT s);
extern VOID Nwrite(BYTE *a, DWORD d, UINT s);
extern VOID Nread2(BYTE *a, DWORD d);
extern VOID Nwrite2(BYTE *a, DWORD d);
extern VOID Nread5(BYTE *a, DWORD d);
extern VOID Nwrite5(BYTE *a, DWORD d);
extern BYTE Read2(DWORD d);
extern DWORD Read5(DWORD d);
extern VOID Write5(DWORD d, DWORD n);
extern VOID ReadIO(BYTE *a, DWORD b, DWORD s);
extern VOID WriteIO(BYTE *a, DWORD b, DWORD s);
// Keyboard.c
extern WORD Keyboard_GetIR();
extern VOID ScanKeyboard();
extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in);
// RPL.c
extern DWORD RPL_SkipOb(DWORD d);
extern DWORD RPL_ObjectSize(BYTE *o);
extern DWORD RPL_CreateTemp(DWORD l);
extern DWORD RPL_Pick(UINT l);
extern VOID RPL_Replace(DWORD n);
extern VOID RPL_Push(DWORD n);
// in External.c
extern VOID External(CHIPSET* w);
// Message Boxes
static __inline int InfoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);}
static __inline int AbortMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);}
static __inline int YesNoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
static __inline int YesNoCancelMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
// Missing Win32 API calls
static __inline LPSTR DuplicateString(LPCSTR szString)
{
UINT uLength = strlen(szString) + 1;
LPSTR szDup = LocalAlloc(0,uLength+1);
CopyMemory(szDup,szString,uLength);
return szDup;
}

Binary file not shown.

View file

@ -1,483 +0,0 @@
/*
* display.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
#include "kml.h"
#define LCD1_ROW 144
#define LCD2_ROW 288
UINT nBackgroundX = 0;
UINT nBackgroundY = 0;
UINT nBackgroundW = 0;
UINT nBackgroundH = 0;
UINT nLcdX = 0;
UINT nLcdY = 0;
BOOL bLcdDoubled = FALSE;
LPBYTE pbyLcd;
HDC hLcdDC;
HDC hMainDC;
static HBITMAP hLcdBitmap;
static HBITMAP hMainBitmap;
static HBITMAP hOldLcdBitmap;
static HBITMAP hOldMainBitmap;
#define B 0xFFFFFF
#define W 0x000000
static struct
{
BITMAPINFOHEADER Lcd_bmih;
DWORD dwColor[32];
} bmiLcd =
{
{0x28,0/*x*/,0/*y*/,1,8,BI_RGB,0,0,0,32,0},
{
B,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,
W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W
}
};
#undef B
#undef W
static DWORD Pattern4[16];
static DWORD Pattern2[4];
VOID UpdateContrast(BYTE byContrast)
{
if (bLcdDoubled)
{
BYTE c = byContrast;
Pattern2[0] = 0;
Pattern2[1] = (c<<8)|(c);
Pattern2[2] = (c<<24)|(c<<16);
Pattern2[3] = (c<<24)|(c<<16)|(c<<8)|(c);
}
else
{
DWORD c = (DWORD)byContrast;
FillMemory(Pattern4, 16*sizeof(DWORD), 0);
Pattern4[0x1] = c;
Pattern4[0x3] = c;
Pattern4[0x5] = c;
Pattern4[0x7] = c;
Pattern4[0x9] = c;
Pattern4[0xB] = c;
Pattern4[0xD] = c;
Pattern4[0xF] = c;
c<<=8;
Pattern4[0x2] |= c;
Pattern4[0x3] |= c;
Pattern4[0x6] |= c;
Pattern4[0x7] |= c;
Pattern4[0xA] |= c;
Pattern4[0xB] |= c;
Pattern4[0xE] |= c;
Pattern4[0xF] |= c;
c<<=8;
Pattern4[0x4] |= c;
Pattern4[0x5] |= c;
Pattern4[0x6] |= c;
Pattern4[0x7] |= c;
Pattern4[0xC] |= c;
Pattern4[0xD] |= c;
Pattern4[0xE] |= c;
Pattern4[0xF] |= c;
c<<=8;
Pattern4[0x8] |= c;
Pattern4[0x9] |= c;
Pattern4[0xA] |= c;
Pattern4[0xB] |= c;
Pattern4[0xC] |= c;
Pattern4[0xD] |= c;
Pattern4[0xE] |= c;
Pattern4[0xF] |= c;
}
return;
}
VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue)
{
bmiLcd.dwColor[nId&0x1F] = (nRed&0xFF)|((nGreen&0xFF)<<8)|((nBlue&0xFF)<<16);
return;
}
VOID CreateLcdBitmap()
{
// create LCD bitmap
if (bLcdDoubled)
{
bmiLcd.Lcd_bmih.biWidth = LCD2_ROW;
bmiLcd.Lcd_bmih.biHeight = -128;
}
else
{
bmiLcd.Lcd_bmih.biWidth = LCD1_ROW;
bmiLcd.Lcd_bmih.biHeight = -64;
}
hLcdDC = CreateCompatibleDC(hWindowDC);
hLcdBitmap = CreateDIBSection(hLcdDC, (BITMAPINFO*)&bmiLcd,
DIB_RGB_COLORS, (LPVOID*)&pbyLcd, NULL, 0);
hOldLcdBitmap = SelectObject(hLcdDC, hLcdBitmap);
UpdateContrast(0x10);
}
VOID DestroyLcdBitmap()
{
if (hLcdDC != NULL)
{
// destroy LCD bitmap
SelectObject(hLcdDC, hOldLcdBitmap);
DeleteObject(hLcdBitmap);
DeleteDC(hLcdDC);
hLcdDC = NULL;
hLcdBitmap = NULL;
hOldLcdBitmap = NULL;
}
return;
}
BOOL CreateMainBitmap(LPSTR szFilename)
{
hMainDC = CreateCompatibleDC(hWindowDC);
hMainBitmap = LoadBitmapFile(szFilename);
if (hMainBitmap == NULL)
{
DeleteDC(hMainDC);
return FALSE;
}
hOldMainBitmap = SelectObject(hMainDC, hMainBitmap);
SelectPalette(hMainDC, hPalette, FALSE);
return TRUE;
}
VOID DestroyMainBitmap()
{
if (hMainDC != NULL)
{
// destroy Main bitmap
SelectObject(hMainDC, hOldMainBitmap);
DeleteObject(hMainBitmap);
DeleteDC(hMainDC);
hMainDC = NULL;
hMainBitmap = NULL;
hOldMainBitmap = NULL;
}
return;
}
//****************
//*
//* LCD functions
//*
//****************
VOID UpdateDisplayPointers()
{
if (Chipset.boffset&4)
{
Chipset.width = Chipset.loffset + 36;
}
else
{
Chipset.width = Chipset.loffset + 34;
}
Chipset.end1 = Chipset.start1 + (Chipset.lcounter+1)*Chipset.width;
if (Chipset.end1 < Chipset.start1)
{
Chipset.start12 = Chipset.end1;
Chipset.end1 = Chipset.start1;
}
else
{
Chipset.start12 = Chipset.start1;
}
Chipset.end2 = Chipset.start2 + (63 - Chipset.lcounter)*34;
}
static BYTE Buf[36];
static BOOL bScreenIsClean = FALSE;
VOID UpdateMainDisplay()
{
UINT x, y;
DWORD d = Chipset.start1;
BYTE *p = pbyLcd;
if (!Chipset.dispon)
{
if (!bScreenIsClean)
{
bScreenIsClean = TRUE;
if (bLcdDoubled)
FillMemory(pbyLcd, LCD2_ROW*64, 0);
else
FillMemory(pbyLcd, LCD1_ROW*64, 0);
}
return;
}
bScreenIsClean = FALSE;
if (bLcdDoubled)
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++,p+=8)
{
*((DWORD*)(p+0))=Pattern2[Buf[x]&3];
*((DWORD*)(p+4))=Pattern2[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=Chipset.width;
}
BitBlt(hWindowDC, nLcdX, nLcdY, 262, (Chipset.lcounter+1)*2, hLcdDC, Chipset.boffset*2, 0, SRCCOPY);
}
else
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++,p+=4) *((DWORD*)p)=Pattern4[Buf[x]];
d+=Chipset.width;
}
BitBlt(hWindowDC, nLcdX, nLcdY, 131, Chipset.lcounter+1, hLcdDC, Chipset.boffset, 0, SRCCOPY);
}
}
VOID UpdateMenuDisplay()
{
UINT x, y;
DWORD d = Chipset.start2;
if (!Chipset.dispon) return;
if (Chipset.lcounter==0x3F) return; // menu disabled
if (bLcdDoubled)
{
BYTE *p = pbyLcd + ((Chipset.lcounter+1)*2*LCD2_ROW);
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++,p+=8)
{
*((DWORD*)(p+0))=Pattern2[Buf[x]&3];
*((DWORD*)(p+4))=Pattern2[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=34;
}
BitBlt(hWindowDC, nLcdX, nLcdY+(Chipset.lcounter+1)*2, 262, (63-Chipset.lcounter)*2, hLcdDC, 0, (Chipset.lcounter+1)*2, SRCCOPY);
}
else
{
BYTE *p = pbyLcd + (Chipset.lcounter+1)*LCD1_ROW;
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++,p+=4) *((DWORD*)p)=Pattern4[Buf[x]];
d+=34;
}
BitBlt(hWindowDC, nLcdX, nLcdY+(Chipset.lcounter+1), 131, 63-Chipset.lcounter, hLcdDC, 0, Chipset.lcounter+1, SRCCOPY);
}
return;
}
VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
{
UINT x0, x;
UINT y0, y;
DWORD *p;
if (Chipset.width<0) return;
d -= Chipset.start1;
y0 = y = d / Chipset.width;
x0 = x = d % Chipset.width;
if ((x0*4+Chipset.boffset)>=131) return;
if (bLcdDoubled)
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<36)
{
p[72] = p[0] = Pattern2[(*a)&3];
p[73] = p[1] = Pattern2[(*a)>>2];
}
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
if (y0!=y)
{
y++;
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0, hLcdDC, Chipset.boffset*2, y0, SRCCOPY);
}
else
{
x0<<=3; x<<=3;
if (x>262) x=262;
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 2, hLcdDC, x0+Chipset.boffset*2, y0, SRCCOPY);
}
}
else
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<36) *p = Pattern4[*a];
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, Chipset.boffset, y0, SRCCOPY);
}
else
{
x0<<=2; x<<=2;
if (x>131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 1, hLcdDC, x0+Chipset.boffset, y0, SRCCOPY);
}
}
return;
}
VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
{
UINT x0, x;
UINT y0, y;
DWORD *p;
if (Chipset.width<0) return;
if (Chipset.lcounter==0x3F) return; // menu disabled
d -= Chipset.start2;
y0 = y = (d / 34) + (Chipset.lcounter+1);
x0 = x = d % 34;
if ((x0*4)>=131) return;
if (bLcdDoubled)
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<34)
{
p[72] = p[0] = Pattern2[(*a)&3];
p[73] = p[1] = Pattern2[(*a)>>2];
}
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
if (y0!=y)
{
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0+2, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=3; x<<=3;
y0<<=1; y<<=1;
if (x>262) x=262;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+2, hLcdDC, x0, y0, SRCCOPY);
}
}
else
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<34) *p = Pattern4[*a];
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=2; x<<=2;
if (x>131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+1, hLcdDC, x0, y0, SRCCOPY);
}
}
return;
}
VOID UpdateAnnunciators()
{
BYTE c;
c = (BYTE)(Chipset.IORam[0xB] | (Chipset.IORam[0xC]<<4));
if (!(c&0x80)) c=0;
DrawAnnunciator(1,c&0x01);
DrawAnnunciator(2,c&0x02);
DrawAnnunciator(3,c&0x04);
DrawAnnunciator(4,c&0x08);
DrawAnnunciator(5,c&0x10);
DrawAnnunciator(6,c&0x20);
return;
}
VOID ResizeWindow()
{
RECT rectWindow;
RECT rectClient;
rectWindow.left = 0;
rectWindow.top = 0;
rectWindow.right = nBackgroundW;
rectWindow.bottom = nBackgroundH;
AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
GetClientRect(hWnd, &rectClient);
AdjustWindowRect(&rectClient, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
if (rectClient.bottom < rectWindow.bottom)
{
rectWindow.bottom += (rectWindow.bottom - rectClient.bottom);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
}
InvalidateRect(hWnd,NULL,TRUE);
return;
}

View file

@ -1,206 +0,0 @@
/*
* engine.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
// HST bits
#define XM 1
#define SB 2
#define SR 4
#define MP 8
#pragma intrinsic(memset,memcpy)
#define w Chipset
#define PCHANGED ((void)(F_s[0]=w.P,F_l[1]=w.P+1))
#define GOYES3 {if(w.carry)goto o_goyes3;else{w.pc+=2;continue;}}
#define GOYES5 {if(w.carry)goto o_goyes5;else{w.pc+=2;continue;}}
#define INTERRUPT ((void)(w.SoftInt=TRUE,bInterrupt=TRUE))
//#define FASTPTR(d) (RMap[d>>12]+(d&0xFFF))
static __inline LPBYTE FASTPTR(DWORD d)
{
return RMap[d>>12]+(d&0xFFF);
}
#include "Ops.h"
BOOL bInterrupt = FALSE;
UINT nState = 1;
UINT nNextState = 0;
CHIPSET Chipset;
UINT SwitchToState(UINT nNewState)
{
UINT nOldState = nState;
if (nState == nNewState) return nOldState;
switch (nState)
{
case 0: // Run
switch (nNewState)
{
case 1: // -> Invalid
nNextState = 1;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
nNextState = 2;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 3: // -> Sleep
nNextState = 3;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
break;
}
break;
case 1: // Invalid
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
bInterrupt = FALSE;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 2;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
break;
case 3: // -> Sleep
nNextState = 3;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
}
break;
case 3: // Sleep
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
if (Chipset.Shutdn) bInterrupt=TRUE;
ResumeThread(hThread);
//while (nState!=nNextState) Sleep(0);
break;
case 1: // -> Invalid
nNextState = 1;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
nNextState = 2;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
}
break;
}
return nOldState;
}
UINT WorkerThread(LPVOID pParam)
{
loop:
while (nNextState == 1)
{
nState = 1;
SuspendThread(hThread);
if (nNextState == 2)
{
nState = 2;
return 0;
}
}
while (nNextState == 0)
{
if (nState!=0)
{
nState = 0;
if (Chipset.type == 'S')
{
Chipset.cards_status &= 0x5;
if (pbyPort2) Chipset.cards_status |= 0x2;
if (bPort2Writeable) Chipset.cards_status |= 0x8;
}
else
{
Chipset.cards_status &= 0xA;
if (pbyPort2) Chipset.cards_status |= 0x1;
if (bPort2Writeable) Chipset.cards_status |= 0x4;
}
UpdateDisplayPointers();
UpdateMainDisplay();
UpdateMenuDisplay();
UpdateAnnunciators();
StartTimers();
}
PCHANGED;
while (!bInterrupt)
{
LPBYTE I = FASTPTR(w.pc);
/**/#include "Fetch.h"
/**/#include "Opcodes.h"
}
if (Chipset.Shutdn)
{
bInterrupt = FALSE;
SuspendThread(hThread);
Chipset.Shutdn = FALSE;
}
if (Chipset.SoftInt)
{
bInterrupt = FALSE;
Chipset.SoftInt = FALSE;
if (Chipset.inte)
{
Chipset.inte = FALSE;
rstkpush(Chipset.pc);
Chipset.pc = 0xf;
}
}
if (nNextState != 0)
{
StopTimers();
Chipset.cards_status &= (Chipset.type=='S')?0x5:0xA;
}
}
while (nNextState == 3)
{
nState = 3;
SuspendThread(hThread);
}
goto loop;
UNREFERENCED_PARAMETER(pParam);
}

View file

@ -1,31 +0,0 @@
/*
* external.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
static __inline VOID Return(CHIPSET* w)
{
w->rstkp=(w->rstkp-1)&7;
w->pc = w->rstk[w->rstkp];
w->rstk[w->rstkp] = 0;
return;
}
VOID External(CHIPSET* w)
{
if (w->pc==0x017A6) // Beep
{
MessageBeep(0xFFFFFFFF);
//Beep(600,50);
Return(w);
return;
}
w->pc +=4;
return;
}

View file

@ -1,92 +0,0 @@
/*
* keyboard.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
WORD Keyboard_GetIR()
{
WORD r = 0;
if (Chipset.out==0) return 0;
if (Chipset.out&0x001) r|=Chipset.Keyboard_Row[0];
if (Chipset.out&0x002) r|=Chipset.Keyboard_Row[1];
if (Chipset.out&0x004) r|=Chipset.Keyboard_Row[2];
if (Chipset.out&0x008) r|=Chipset.Keyboard_Row[3];
if (Chipset.out&0x010) r|=Chipset.Keyboard_Row[4];
if (Chipset.out&0x020) r|=Chipset.Keyboard_Row[5];
if (Chipset.out&0x040) r|=Chipset.Keyboard_Row[6];
if (Chipset.out&0x080) r|=Chipset.Keyboard_Row[7];
if (Chipset.out&0x100) r|=Chipset.Keyboard_Row[8];
return r;
}
VOID ScanKeyboard()
{
WORD IR = Keyboard_GetIR();
Chipset.in = IR | Chipset.IR15X;
if (Chipset.IR15X)
{
if (Chipset.inte)
{
// PatBlt(hWindowDC,0,0,8,8,DSTINVERT);
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
if (Chipset.Shutdn)
{
// PatBlt(hWindowDC,8,0,8,8,DSTINVERT);
Chipset.Shutdn = FALSE; // Prevent another ResumeThread
ResumeThread(hThread);
}
}
if (IR != 0)
{
if ((Chipset.inte) && (Chipset.intk))
{
// PatBlt(hWindowDC,0,8,8,8,DSTINVERT);
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
if (Chipset.Shutdn)
{
// PatBlt(hWindowDC,8,8,8,8,DSTINVERT);
Chipset.Shutdn = FALSE; // Prevent another ResumeThread
ResumeThread(hThread);
}
}
return;
}
VOID KeyboardEvent(BOOL bPress, UINT out, UINT in)
{
if (nState != 0)
return;
if (in == 0x8000)
{
Chipset.IR15X = bPress?0x8000:0x0000;
}
else
{
_ASSERT(out<9);
if (bPress)
{
if (((Chipset.Keyboard_Row[out]&in) == 0) && (Chipset.inte==FALSE) && (Chipset.intk))
Chipset.intd = TRUE;
Chipset.Keyboard_Row[out] |= in;
}
else
Chipset.Keyboard_Row[out] &= (~in);
}
ScanKeyboard();
return;
}

View file

@ -1,988 +0,0 @@
/*
* mops.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
#define SXCONFIG 1
// CRC calculation
static WORD crc_table[16] =
{
0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F
};
static __inline VOID CRC(BYTE nib)
{
Chipset.crc = (WORD)((Chipset.crc>>4)^crc_table[(Chipset.crc^nib)&0xf]);
}
LPBYTE RMap[256] = {NULL,};
LPBYTE WMap[256] = {NULL,};
static __inline UINT MIN(UINT a, UINT b)
{
return (a<b)?a:b;
}
static __inline UINT MAX(UINT a, UINT b)
{
return (a>b)?a:b;
}
static VOID MapP0(BYTE a, BYTE b)
{
UINT i;
DWORD p, m;
a = (BYTE)MAX(a,Chipset.P0Base);
b = (BYTE)MIN(b,Chipset.P0End);
m = (Chipset.Port0Size*2048)-1;
p = ((a-Chipset.P0Base)<<12)&m;
for (i=a; i<=b; i++)
{
RMap[i]=Chipset.Port0 + p;
WMap[i]=Chipset.Port0 + p;
p = (p+0x1000)&m;
}
return;
}
static VOID MapBS(BYTE a, BYTE b)
{
UINT i;
DWORD p, m;
a = (BYTE)MAX(a,Chipset.BSBase);
b = (BYTE)MIN(b,Chipset.BSEnd);
m = (dwRomSize-1)&0xFF000;
p = a*0x1000;
for (i=a;i<=b;i++)
{
RMap[i]=pbyRom + p;
WMap[i]=NULL;
p = (p+0x1000)&m;
}
return;
}
static VOID MapP1(BYTE a, BYTE b)
{
UINT i;
DWORD p, m;
if (Chipset.Port1 == NULL) return;
a = (BYTE)MAX(a,Chipset.P1Base);
b = (BYTE)MIN(b,Chipset.P1End);
m = (Chipset.Port1Size*2048)-1;
p = ((a-Chipset.P1Base)<<12)&m;
if (Chipset.Port1_Writeable)
{
for (i=a; i<=b; i++)
{
RMap[i]=Chipset.Port1 + p;
WMap[i]=Chipset.Port1 + p;
p = (p+0x1000)&m;
}
}
else
{
for (i=a; i<=b; i++)
{
RMap[i]=Chipset.Port1 + p;
WMap[i]=NULL;
p = (p+0x1000)&m;
}
}
return;
}
static VOID MapP2(BYTE a, BYTE b)
{
UINT i;
DWORD p, m;
LPBYTE pbyTemp;
if (pbyPort2 == NULL) return;
pbyTemp = pbyPort2 + (nPort2Bank << 18);
a = (BYTE)MAX(a,Chipset.P2Base);
b = (BYTE)MIN(b,Chipset.P2End);
m = (Chipset.Port2Size*2048)-1;
p = ((a-Chipset.P2Base)<<12)&m;
if (bPort2Writeable)
{
for (i=a; i<=b; i++)
{
RMap[i]=pbyTemp + p;
WMap[i]=pbyTemp + p;
p = (p+0x1000)&m;
}
}
else
{
for (i=a; i<=b; i++)
{
RMap[i]=pbyTemp + p;
WMap[i]=NULL;
p = (p+0x1000)&m;
}
}
return;
}
static VOID MapROM(BYTE a, BYTE b)
{
UINT i;
DWORD p, m;
m = (dwRomSize-1)&0xFF000;
p = a*0x1000;
for (i=a;i<=b;i++)
{
RMap[i]=pbyRom + p;
WMap[i]=NULL;
p = (p+0x1000)&m;
}
return;
}
VOID Map(BYTE a, BYTE b)
{
#if SXCONFIG
if (cCurrentRomType=='S')
{
MapROM(a,b);
if (Chipset.BSCfig) MapBS(a,b);
if (Chipset.P2Cfig) MapP2(a,b);
if (Chipset.P1Cfig) MapP1(a,b);
if (Chipset.P0Cfig) MapP0(a,b);
return;
}
#endif
MapROM(a,b);
if (Chipset.P2Cfig) MapP2(a,b);
if (Chipset.P1Cfig) MapP1(a,b);
if (Chipset.BSCfig) MapBS(a,b);
if (Chipset.P0Cfig) MapP0(a,b);
return;
}
////////////////////////////////////////////////////////////////////////////////
//
// Bus Commands
//
////////////////////////////////////////////////////////////////////////////////
VOID Config()
{
DWORD d = Npack(Chipset.C,5);
BYTE b = (BYTE)(d>>12);
BYTE s = (BYTE)(b^0xFF);
#if SXCONFIG
if (cCurrentRomType=='S')
{
if (!Chipset.IOCfig)
{
Chipset.IOCfig=TRUE;
Chipset.IOBase=d&0xFFFC0;
Map(b,b);
return;
}
if (!Chipset.P0Cfg2)
{
Chipset.P0Cfg2=TRUE;
Chipset.P0Size=s;
return;
}
if (!Chipset.P0Cfig)
{
Chipset.P0Cfig = TRUE;
Chipset.P0Base = (BYTE)b;
Chipset.P0End = (BYTE)(b+Chipset.P0Size);
Map(Chipset.P0Base,Chipset.P0End);
return;
}
if (!Chipset.P1Cfg2)
{
Chipset.P1Cfg2 = TRUE;
Chipset.P1Size = (BYTE)s;
return;
}
if (!Chipset.P1Cfig)
{
Chipset.P1Cfig = TRUE;
Chipset.P1Base = (BYTE)b;
Chipset.P1End = (BYTE)(b+Chipset.P1Size);
Map(Chipset.P1Base,Chipset.P1End);
return;
}
if (!Chipset.P2Cfg2)
{
Chipset.P2Cfg2 = TRUE;
Chipset.P2Size = (BYTE)s;
return;
}
if (!Chipset.P2Cfig)
{
Chipset.P2Cfig = TRUE;
Chipset.P2Base = (BYTE)b;
Chipset.P2End = (BYTE)(b+Chipset.P2Size);
Map(Chipset.P2Base,Chipset.P2End);
return;
}
if (!Chipset.BSCfg2)
{
Chipset.BSCfg2=TRUE;
Chipset.BSSize=s;
return;
}
if (!Chipset.BSCfig)
{
Chipset.BSCfig = TRUE;
Chipset.BSBase = (BYTE)b;
Chipset.BSEnd = (BYTE)(b+Chipset.BSSize);
Map(Chipset.BSBase,Chipset.BSEnd);
return;
}
return;
}
#endif
if (!Chipset.IOCfig)
{
Chipset.IOCfig=TRUE;
Chipset.IOBase=d&0xFFFC0;
Map(b,b);
return;
}
if (!Chipset.P0Cfg2)
{
Chipset.P0Cfg2=TRUE;
Chipset.P0Size=s;
return;
}
if (!Chipset.P0Cfig)
{
Chipset.P0Cfig = TRUE;
Chipset.P0Base = (BYTE)b;
Chipset.P0End = (BYTE)(b+Chipset.P0Size);
Map(Chipset.P0Base,Chipset.P0End);
return;
}
if (!Chipset.BSCfg2)
{
Chipset.BSCfg2=TRUE;
Chipset.BSSize=s;
return;
}
if (!Chipset.BSCfig)
{
Chipset.BSCfig = TRUE;
Chipset.BSBase = (BYTE)b;
Chipset.BSEnd = (BYTE)(b+Chipset.BSSize);
Map(Chipset.BSBase,Chipset.BSEnd);
return;
}
if (!Chipset.P1Cfg2)
{
Chipset.P1Cfg2 = TRUE;
Chipset.P1Size = (BYTE)s;
return;
}
if (!Chipset.P1Cfig)
{
Chipset.P1Cfig = TRUE;
Chipset.P1Base = (BYTE)b;
Chipset.P1End = (BYTE)(b+Chipset.P1Size);
Map(Chipset.P1Base,Chipset.P1End);
return;
}
if (!Chipset.P2Cfg2)
{
Chipset.P2Cfg2 = TRUE;
Chipset.P2Size = (BYTE)s;
return;
}
if (!Chipset.P2Cfig)
{
Chipset.P2Cfig = TRUE;
Chipset.P2Base = (BYTE)b;
Chipset.P2End = (BYTE)(b+Chipset.P2Size);
Map(Chipset.P2Base,Chipset.P2End);
return;
}
return;
}
VOID Uncnfg()
{
DWORD d=Npack(Chipset.C,5);
BYTE b=(BYTE)(d>>12);
#if SXCONFIG
if (cCurrentRomType=='S')
{
if ((Chipset.IOCfig)&&(d==Chipset.IOBase)) {Chipset.IOCfig=FALSE;Chipset.IOBase=0x100000;Map(b,b);return;}
if ((Chipset.P0Cfig)&&(b==Chipset.P0Base)) {Chipset.P0Cfig=FALSE;Chipset.P0Cfg2=FALSE;Map(Chipset.P0Base,Chipset.P0End);return;}
if ((Chipset.P1Cfig)&&(b==Chipset.P1Base)) {Chipset.P1Cfig=FALSE;Chipset.P1Cfg2=FALSE;Map(Chipset.P1Base,Chipset.P1End);return;}
if ((Chipset.P2Cfig)&&(b==Chipset.P2Base)) {Chipset.P2Cfig=FALSE;Chipset.P2Cfg2=FALSE;Map(Chipset.P2Base,Chipset.P2End);return;}
if ((Chipset.BSCfig)&&(b==Chipset.BSBase)) {Chipset.BSCfig=FALSE;Chipset.BSCfg2=FALSE;Map(Chipset.BSBase,Chipset.BSEnd);return;}
return;
}
#endif
if ((Chipset.IOCfig)&&(d==Chipset.IOBase)) {Chipset.IOCfig=FALSE;Chipset.IOBase=0x100000;Map(b,b);return;}
if ((Chipset.P0Cfig)&&(b==Chipset.P0Base)) {Chipset.P0Cfig=FALSE;Chipset.P0Cfg2=FALSE;Map(Chipset.P0Base,Chipset.P0End);return;}
if ((Chipset.BSCfig)&&(b==Chipset.BSBase)) {Chipset.BSCfig=FALSE;Chipset.BSCfg2=FALSE;Map(Chipset.BSBase,Chipset.BSEnd);return;}
if ((Chipset.P1Cfig)&&(b==Chipset.P1Base)) {Chipset.P1Cfig=FALSE;Chipset.P1Cfg2=FALSE;Map(Chipset.P1Base,Chipset.P1End);return;}
if ((Chipset.P2Cfig)&&(b==Chipset.P2Base)) {Chipset.P2Cfig=FALSE;Chipset.P2Cfg2=FALSE;Map(Chipset.P2Base,Chipset.P2End);return;}
return;
}
VOID Reset()
{
Chipset.IOCfig=FALSE;Chipset.IOBase=0x100000;
Chipset.P0Cfig=FALSE;Chipset.P0Cfg2=FALSE;Chipset.P0Base=0;Chipset.P0Size=0;Chipset.P0End=0;
Chipset.BSCfig=FALSE;Chipset.BSCfg2=FALSE;Chipset.BSBase=0;Chipset.BSSize=0;Chipset.BSEnd=0;
Chipset.P1Cfig=FALSE;Chipset.P1Cfg2=FALSE;Chipset.P1Base=0;Chipset.P1Size=0;Chipset.P1End=0;
Chipset.P2Cfig=FALSE;Chipset.P2Cfg2=FALSE;Chipset.P2Base=0;Chipset.P2Size=0;Chipset.P2End=0;
Map(0x00,0xFF);
return;
}
VOID C_Eq_Id()
{
#if SXCONFIG
if (cCurrentRomType=='S')
{
if (!Chipset.IOCfig) {Nunpack(Chipset.C,(Chipset.IOBase*0x1000)^0x00019,5);return;}
if (!Chipset.P0Cfg2) {Nunpack(Chipset.C,(Chipset.P0Size*0x1000)^0xFF003,5);return;}
if (!Chipset.P0Cfig) {Nunpack(Chipset.C,(Chipset.P0Base*0x1000)^0x000F4,5);return;}
if (!Chipset.P1Cfg2) {Nunpack(Chipset.C,(Chipset.P1Size*0x1000)^0xFF005,5);return;}
if (!Chipset.P1Cfig) {Nunpack(Chipset.C,(Chipset.P1Base*0x1000)^0x000F6,5);return;}
if (!Chipset.P2Cfg2) {Nunpack(Chipset.C,(Chipset.P2Size*0x1000)^0xFF007,5);return;}
if (!Chipset.P2Cfig) {Nunpack(Chipset.C,(Chipset.P2Base*0x1000)^0x000F8,5);return;}
if (!Chipset.BSCfg2) {Nunpack(Chipset.C,(Chipset.BSSize*0x1000)^0xFF001,5);return;}
if (!Chipset.BSCfig) {Nunpack(Chipset.C,(Chipset.BSBase*0x1000)^0x000F2,5);return;}
memset(Chipset.C,0,5);
return;
}
#endif
if (!Chipset.IOCfig) {Nunpack(Chipset.C,(Chipset.IOBase*0x1000)^0x00019,5);return;}
if (!Chipset.P0Cfg2) {Nunpack(Chipset.C,(Chipset.P0Size*0x1000)^0xFF003,5);return;}
if (!Chipset.P0Cfig) {Nunpack(Chipset.C,(Chipset.P0Base*0x1000)^0x000F4,5);return;}
if (!Chipset.BSCfg2) {Nunpack(Chipset.C,(Chipset.BSSize*0x1000)^0xFF005,5);return;}
if (!Chipset.BSCfig) {Nunpack(Chipset.C,(Chipset.BSBase*0x1000)^0x000F6,5);return;}
if (!Chipset.P1Cfg2) {Nunpack(Chipset.C,(Chipset.P1Size*0x1000)^0xFF007,5);return;}
if (!Chipset.P1Cfig) {Nunpack(Chipset.C,(Chipset.P1Base*0x1000)^0x000F8,5);return;}
if (!Chipset.P2Cfg2) {Nunpack(Chipset.C,(Chipset.P2Size*0x1000)^0xFF001,5);return;}
if (!Chipset.P2Cfig) {Nunpack(Chipset.C,(Chipset.P2Base*0x1000)^0x000F2,5);return;}
memset(Chipset.C,0,5);
return;
}
VOID Npeek(BYTE *a, DWORD d, UINT s)
{
DWORD u, v;
UINT c;
BYTE *p;
do
{
u = d>>12;
v = d&0xFFF;
c = MIN(s,0x1000-v);
if ((p=RMap[u]) != NULL) memcpy(a, p+v, c);
if (s-=c) {a+=c; d+=c;}
} while (s);
return;
}
VOID Nread(BYTE *a, DWORD d, UINT s)
{
DWORD u, v;
UINT c;
BYTE *p;
do
{
if ((d&0xFFFC0)==Chipset.IOBase)
{
v = d&0x3F;
c = MIN(s,0x40-v);
ReadIO(a,v,c);
}
else
{
u = d>>12;
v = d&0xFFF;
c = MIN(s,0x1000-v);
if ((p=RMap[u]) != NULL)
{
memcpy(a, p+v, c);
for (u=0; u<c; u++)
CRC(a[u]);
}
}
if (s-=c) {a+=c; d+=c;}
} while (s);
return;
}
VOID Nwrite(BYTE *a, DWORD d, UINT s)
{
DWORD u, v;
UINT c;
BYTE *p;
if ((d<Chipset.end1)&&(d>=Chipset.start12))
WriteToMainDisplay(a,d,s);
if ((d<Chipset.end2)&&(d>=Chipset.start2))
WriteToMenuDisplay(a,d,s);
do
{
if ((d&0xFFFC0)==Chipset.IOBase)
{
v = d&0x3F;
c = MIN(s,0x40-v);
WriteIO(a, v, c);
}
else
{
u = d>>12;
v = d&0xFFF;
c = MIN(s,0x1000-v);
if ((p=WMap[u]) != NULL) memcpy(p+v, a, c);
}
a+=c;
d+=c;
} while (s-=c);
return;
}
VOID Nread2(BYTE *a, DWORD d)
{
DWORD u, v;
BYTE *p;
if ((d&0xFFFC0)==Chipset.IOBase)
{
u = d&0x3F;
if (u>0x3E) {Nread(a,d,2);return;}
ReadIO(a,u,2);
return;
}
u = d>>12;
v = d&0xFFF;
if (u==Chipset.BSBase) // bank switching
{
nPort2Bank = (v&dwPort2Mask)>>1;
Map(Chipset.P2Base,Chipset.P2End);
a[0] = 3;
a[1] = 3;
return;
}
if (v>0xFFE) {Nread(a,d,2);return;}
if ((p=RMap[u]) != NULL)
{
*((WORD*)a) = *((WORD*)(p+v));
CRC(a[0]);
CRC(a[1]);
}
return;
}
VOID Nwrite2(BYTE *a, DWORD d)
{
DWORD u, v;
BYTE *p;
if ((d&0xFFFC0)==Chipset.IOBase) {Nwrite(a,d,2);return;}
u = d>>12;
v = d&0xFFF;
if (v>0xFFE) {Nwrite(a,d,2);return;}
if ((d<Chipset.end1)&&(d>=Chipset.start12))
WriteToMainDisplay(a,d,2);
if ((d<Chipset.end2)&&(d>=Chipset.start2))
WriteToMenuDisplay(a,d,2);
if ((p=WMap[u]) != NULL)
{
*((WORD*)(p+v)) = *((WORD*)a);
}
return;
}
VOID Nread5(BYTE *a, DWORD d)
{
DWORD u, v;
BYTE *p;
if ((d&0xFFFC0)==Chipset.IOBase)
{
u = d&0x3F;
if (u>0x3A) {Nread(a,d,5);return;}
ReadIO(a,u,5);
return;
}
v = d&0xFFF;
if (v>0xFFA) {Nread(a,d,5);return;}
u = d>>12;
if ((p=RMap[u]) != NULL)
{
*((DWORD*)a) = *((DWORD*)(p+v));
a[4] = p[v+4];
CRC(a[0]);
CRC(a[1]);
CRC(a[2]);
CRC(a[3]);
CRC(a[4]);
}
return;
}
VOID Nwrite5(BYTE *a, DWORD d)
{
DWORD u, v;
BYTE *p;
if ((d&0xFFFC0)==Chipset.IOBase) {Nwrite(a,d,5);return;}
v = d&0xFFF;
if (v>0xFFA) {Nwrite(a,d,5);return;}
if ((d<Chipset.end1)&&(d>=Chipset.start12)) WriteToMainDisplay(a,d,5);
if ((d<Chipset.end2)&&(d>=Chipset.start2)) WriteToMenuDisplay(a,d,5);
u = d>>12;
if ((p=WMap[u]) != NULL)
{
*((DWORD*)(p+v)) = *((DWORD*)a);
p[v+4] = a[4];
}
}
DWORD Read5(DWORD d)
{
BYTE p[8];
Npeek(p,d,5);
return Npack(p,5);
}
BYTE Read2(DWORD d)
{
BYTE p[2];
Npeek(p,d,2);
return (BYTE)(p[0]|(p[1]<<4));
}
VOID Write5(DWORD d, DWORD n)
{
BYTE p[8];
Nunpack(p,n,5);
Nwrite(p,d,5);
return;
}
VOID ReadIO(BYTE *a, DWORD b, DWORD s)
{
DWORD d = b;
do
{
switch (d)
{
case 0x00: *a = (Chipset.dispon<<3)|Chipset.boffset; break;
case 0x01: *a = Chipset.contrast&0xF; break;
case 0x02: *a = Chipset.contrast>>4; break;
case 0x03: *a = 0;
case 0x04: *a = (Chipset.crc )&0xF; break;
case 0x05: *a = (Chipset.crc>> 4)&0xF; break;
case 0x06: *a = (Chipset.crc>> 8)&0xF; break;
case 0x07: *a = (Chipset.crc>>12)&0xF; break;
case 0x08: *a = 0; break;
// case 0x09: *a = Chipset.IORam[0x09]; break;
case 0x0A: *a = 0; break;
// case 0x0B: *a = Chipset.IORam[0x0B]; break;
// case 0x0C: *a = Chipset.IORam[0x0C]; break;
// case 0x0D: *a = Chipset.IORam[0x0D]; break;
// case 0x0E: *a = Chipset.IORam[0x0E]; break;
case 0x0F: *a = Chipset.cards_status; break;
// case 0x10: *a = Chipset.IORam[0x10]; break;
// case 0x11: *a = Chipset.IORam[0x11]; break;
case 0x12: *a = 0; break;
case 0x13: *a = 0; break;
case 0x14: *a = 0; Chipset.IORam[0x11]&=0xE; break;
case 0x15: *a = 0; Chipset.IORam[0x11]&=0xE; break;
case 0x16: *a = 0; break;
case 0x17: *a = 0; break;
// case 0x18: *a = Chipset.IORam[0x18]; break;
// case 0x19: *a = Chipset.IORam[0x19]; break;
case 0x1A: *a = 0; break;
case 0x1B: *a = 0; break;
case 0x1C: *a = 0; break;
case 0x1D: *a = 0; break;
// case 0x1E: *a = Chipset.IORam[0x1E]; break;
// case 0x1F: *a = Chipset.IORam[0x1F]; break;
case 0x20: *a = 3; break;
case 0x21: *a = 3; break;
case 0x22: *a = 3; break;
case 0x23: *a = 3; break;
case 0x24: *a = 3; break;
case 0x25: *a = 3; break;
case 0x26: *a = 3; break;
case 0x27: *a = 3; break;
case 0x28:
if (Chipset.sync)
Chipset.sync--;
else
Chipset.sync=Chipset.lcounter+1;
*a = Chipset.sync&0xF;
break;
case 0x29:
if (d==b)
{
if (Chipset.sync)
Chipset.sync--;
else
Chipset.sync=Chipset.lcounter+1;
}
*a = Chipset.sync&0xF;
break;
case 0x2A: *a = 0; break;
case 0x2B: *a = 0; break;
case 0x2C: *a = 0; break;
case 0x2D: *a = 0; break;
// case 0x2E: *a = Chipset.IORam[0x2E]; break;
// case 0x2F: *a = Chipset.IORam[0x2F]; break;
case 0x30: *a = 3; break;
case 0x31: *a = 3; break;
case 0x32: *a = 3; break;
case 0x33: *a = 3; break;
case 0x34: *a = 3; break;
case 0x35: *a = 0; break;
case 0x36: *a = 0; break;
case 0x37: *a = ReadT1(); break;
case 0x38: Nunpack(a, ReadT2() , s); return;
case 0x39: Nunpack(a, ReadT2()>> 4, s); return;
case 0x3A: Nunpack(a, ReadT2()>> 8, s); return;
case 0x3B: Nunpack(a, ReadT2()>>12, s); return;
case 0x3C: Nunpack(a, ReadT2()>>16, s); return;
case 0x3D: Nunpack(a, ReadT2()>>20, s); return;
case 0x3E: Nunpack(a, ReadT2()>>24, s); return;
case 0x3F: Nunpack(a, ReadT2()>>28, s); return;
default: *a = Chipset.IORam[d];
}
d++; a++;
} while (--s);
return;
}
VOID WriteIO(BYTE *a, DWORD b, DWORD s)
{
DWORD d=b;
BYTE c;
BYTE disp=0;
if (d>=0x38)
{
Nunpack(Chipset.IORam+0x38, ReadT2(), 8);
memcpy(Chipset.IORam+d,a,s);
SetT2(Npack(Chipset.IORam+0x38,8));
return;
}
do
{
c = *a;
switch (d)
{
// 00100 = NS:DISPIO
// 00100 @ Display bit offset and DON [DON OFF2 OFF1 OFF0]
// 00100 @ 3 nibs for display offset (scrolling), DON=Display ON
case 0x00:
if ((c^Chipset.IORam[d])&8)
{
Chipset.dispon = c>>3;
disp|=7;
}
if ((c^Chipset.IORam[d])&7)
{
Chipset.boffset = c&7;
disp|=3;
}
Chipset.IORam[d] = c;
break;
// 00101 = NS:CONTRLSB
// 00101 @ Contrast Control [CON3 CON2 CON1 CON0]
// 00101 @ Higher value = darker screen
case 0x01:
if (c!=Chipset.IORam[d])
{
Chipset.IORam[d]=c;
Chipset.contrast = (Chipset.contrast&0x10)|c;
UpdateContrast(Chipset.contrast);
disp|=7;
}
break;
// 00102 = NS:DISPTEST
// 00102 @ Display test [VDIG LID TRIM CON4] [LRT LRTD LRTC BIN]
// 00102 @ Normally zeros
case 0x02:
if (c!=Chipset.IORam[d])
{
Chipset.IORam[d]=c;
Chipset.contrast = (Chipset.contrast&0x0f)|((c&1)<<4);
UpdateContrast(Chipset.contrast);
disp|=7;
}
break;
case 0x03: Chipset.IORam[d]=c; break;
// 00104 = HP:CRC
// 00104 @ 16 bit hardware CRC (104-107) (X^16+X^12+X^5+1)
// 00104 @ crc = ( crc >> 4 ) ^ ( ( ( crc ^ nib ) & 0x000F ) * 0x1081 );
case 0x04: Chipset.crc = (Chipset.crc&0xfff0)|(c*0x0001); break;
case 0x05: Chipset.crc = (Chipset.crc&0xff0f)|(c*0x0010); break;
case 0x06: Chipset.crc = (Chipset.crc&0xf0ff)|(c*0x0100); break;
case 0x07: Chipset.crc = (Chipset.crc&0x0fff)|(c*0x1000); break;
// 00108 = NS:POWERSTATUS
// 00108 @ Low power registers (108-109)
// 00108 @ [LB2 LB1 LB0 VLBI] (read only)
// 00108 @ LowBat(2) LowBat(1) LowBat(S) VeryLowBat
case 0x08: break; // read-only
// 00109 = NS:POWERCTRL
// 00109 @ [ELBI EVLBI GRST RST] (read/write)
case 0x09: Chipset.IORam[d]=c; break;
// 0010A = NS:MODE
// 0010A @ Mode Register (read-only)
case 0x0A: break; // read-only
// 0010B = HP:ANNCTRL
// 0010B @ Annunciator control [LA4 LA3 LA2 LA1] = [ alarm alpha -> <- ]
case 0x0B:
case 0x0C:
if (c!=Chipset.IORam[d])
{
Chipset.IORam[d] = c;
disp|=8;
}
break;
// 0010D = NS:BAU
// 0010D @ Serial baud rate [UCK BD2 BD1 BD0] (bit 3 is read-only)
// 0010D @ 3 bits = {1200 1920 2400 3840 4800 7680 9600 15360}
case 0x0D: Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7); break; // bit 3 is read-only
// 0010E = NS:CARDCTRL
// 0010E @ [ECDT RCDT SMP SWINT] (read/write)
// 0010E @ Enable Card Det., Run Card Det., Set Module Pulled, Software interrupt
case 0x0E:
Chipset.IORam[d]=c;
#if 1
if ( (RMap[4]!=(pbyRom+0x4000)) && (12 != c) )
{
c |= 0x10;
}
#endif
if (c&1)
{
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
if (c&2)
{
Chipset.HST |= 8; // MP
// Chipset.SoftInt = TRUE;
// bInterrupt = TRUE;
}
break;
// 0010F = NS:CARDSTATUS
// 0010F @ [P2W P1W P2C P1C] (read-only) Port 2 writable .. Port 1 inserted
case 0x0F: break; // read-only
// 00110 = HP:IOC
// 00110 @ Serial I/O Control [SON ETBE ERBF ERBZ]
// 00110 @ Serial On, Interrupt On Recv.Buf.Empty, Full, Buzy
case 0x10: Chipset.IORam[d]=c; break;
// 00111 = HP:RCS
// 00111 Serial Receive Control/Status [RX RER RBZ RBF] (bit 3 is read-only)
case 0x11: Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7); break;
// 00112 = HP:TCS
// 00112 @ Serial Transmit Control/Status [BRK LPB TBZ TBF]
case 0x12: Chipset.IORam[d]=c; break;
// 00113 = HP:CRER
// 00113 @ Serial Clear RER (writing anything clears RER bit)
case 0x13: Chipset.IORam[0x11]&=0xB; Chipset.IORam[0x11]&=0xB;
// 00114 = HP:RBR
// 00114 @ Serial Receive Buffer Register (Reading clears RBF bit)
// 00114 @ [RX RER RBZ RBF]
case 0x14: break; // probably read-only
case 0x15: break; // probably read-only
// 00116 = HP:TBR
// 00116 @ Serial Transmit Buffer Register (Writing sets TBF bit)
case 0x16: Chipset.IORam[d]=c; Chipset.IORam[0x12]|=1; break;
case 0x17: Chipset.IORam[d]=c; Chipset.IORam[0x12]|=1; break;
// 00118 = NS:SRR
// 00118 @ Service Request Register (read-only)
// 00118 @ [ISRQ TSRQ USRQ VSRQ] [KDN NINT2 NINT LSRQ]
case 0x18: break; // read-only
case 0x19: break; // read-only
// 0011A = HP:IRC
// 0011A @ IR Control Register [IRI EIRU EIRI IRE] (bit 3 is read-only)
// 0011A @ IR Input, Enable IR UART mode, Enable IR Interrupt, IR Event
case 0x1A: Chipset.IORam[d]=(Chipset.IORam[d]&8)|(c&7); break;
// 0011B = NS:BASENIBOFF
// 0011B @ Used as addressto get BASENIB from 11F to the 5th nibble
case 0x1B: break;
// 0011C = NS:LCR
// 0011C @ Led Control Register [LED ELBE LBZ LBF] (Setting LED is draining)
case 0x1C: Chipset.IORam[d]=c; break;
// 0011D = NS:LBR
// 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero)
case 0x1D: Chipset.IORam[d]=c&1; break;
// 0011E = NS:SCRATCHPAD
// 0011E @ Scratch pad
case 0x1E: Chipset.IORam[d]=c; break;
// 0011F = NS:BASENIB
// 0011F @ 7 or F for base memory
case 0x1F: Chipset.IORam[d]=c; break;
// 00120 = NS:DISPADDR
// 00120 @ Display Start Address (write only)
// 00120 @ bit 0 is ignored (display must start on byte boundary)
case 0x20:
if (s>=5)
{
b = Npack(a,5)&0xFFFFE;
if (b != Chipset.start1)
{
Chipset.start1 = b;
disp|=3;
}
b = d;
}
Chipset.IORam[d]=c;
break;
// case 0x21: Chipset.IORam[d]=c; break;
// case 0x22: Chipset.IORam[d]=c; break;
// case 0x23: Chipset.IORam[d]=c; break;
// case 0x24: Chipset.IORam[d]=c; break;
// 00125 = NS:LINEOFFS
// 00125 @ Display Line offset (write only) (no of bytes skipped after each line)
// 00125 @ MSG sign extended
case 0x25:
if (s>=3)
{
signed short lo = (signed short)Npack(a, 3);
if (lo&0x800) lo-=0x1000;
if (lo==Chipset.loffset) break;
Chipset.loffset = lo;
disp|=3;
}
break;
// 00128 = NS:LINECOUNT
// 00128 @ Display Line Counter and miscellaneous (28-29)
// 00128 @ [LC3 LC2 LC1 LC0] [DA19 M32 LC5 LC4]
// 00128 @ Line counter 6 bits -> max = 2^6-1 = 63 = disp height
// 00128 @ Normally has 55 -> Menu starts at display row 56
case 0x28: Chipset.IORam[d]=c; break;
case 0x29:
Chipset.IORam[d]=c;
d = Npack(Chipset.IORam+0x28,2)&0x3F;
if (Chipset.lcounter != d)
{
Chipset.lcounter = d;
disp|=7;
}
break;
case 0x2A: break;
case 0x2B: break;
case 0x2C: break;
case 0x2D: break;
// 0012E = NS:TIMER1CTRL
// 0012E @ TIMER1 Control [SRQ WKE INT XTRA]
case 0x2E: Chipset.IORam[d]=c&0xE; break;
// 0012F = NS:TIMER2CTRL
// 0012F @ TIMER2 Control [SRQ WKE INT RUN]
case 0x2F:
// if ((Chipset.IORam[d]^c)&1)
// // RUN changed
Chipset.IORam[d]=c;
if (c&1)
StartTimers();
else
StopTimers();
break;
// 00130 = NS:MENUADDR
// 00130 @ Display Secondary Start Address (write only) (30-34)
// 00130 @ Menu Display Address, no line offsets
case 0x30:
if (s>=5)
{
b = Npack(a,5)&0xFFFFE;
if (b != Chipset.start2)
{
Chipset.start2 = b;
disp|=5;
}
b = d;
}
Chipset.IORam[d]=c;
break;
// case 0x31: Chipset.IORam[d]=c; break;
// case 0x32: Chipset.IORam[d]=c; break;
// case 0x33: Chipset.IORam[d]=c; break;
// case 0x34: Chipset.IORam[d]=c; break;
case 0x35: break;
case 0x36: break;
// 00137 = HP:TIMER1
// 00137 @ Decremented 16 times/s
case 0x37:
SetT1(Chipset.t1);
break;
// 00138 = HP:TIMER2
// 00138 @ hardware timer (38-3F), decremented 8192 times/s
// nothing - fall through to default
default: Chipset.IORam[d]=c;
}
a++; d++;
} while (--s);
if (disp&1) UpdateDisplayPointers();
if (disp&2) UpdateMainDisplay();
if (disp&4) UpdateMenuDisplay();
if (disp&8) UpdateAnnunciators();
return;
}

File diff suppressed because it is too large Load diff

View file

@ -1,64 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Emu48.rc
//
#define IDI_EMU48 100
#define IDR_MENU 101
#define IDB_EMPTY 102
#define IDD_ABOUT 103
#define IDD_ABOUTS 104
#define IDD_SETTINGS 105
#define IDD_CHOOSEKML 106
#define IDD_KMLLOG 107
#define IDD_REGISTER 110
#define IDC_PORT1WR 1000
#define IDC_AUTOSAVE 1001
#define IDC_AUTOSAVEONEXIT 1002
#define IDC_EMU48DIR 1003
#define IDC_BROWSEDIR 1004
#define IDC_REFRESH 1004
#define IDC_KMLSCRIPT 1005
#define IDC_AUTHOR 1006
#define IDC_TITLE 1007
#define IDC_KMLLOG 1008
#define IDC_VERSION 1010
#define IDC_PORT2ISSHARED 1011
#define IDC_PORT2 1012
#define IDC_T1PERIOD 1013
#define IDC_ALWAYSDISPLOG 1016
#define IDC_T1DEFAULT 1019
#define IDC_NAME 1020
#define IDC_REGTEXT 1021
#define IDC_CODE 1022
#define IDC_REGISTER 1022
#define IDC_UPDATE 1024
#define IDC_USEMMTIMER 1025
#define IDC_LICENSE 1026
#define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003
#define ID_FILE_SAVEAS 40004
#define ID_FILE_EXIT 40005
#define ID_VIEW_COPY 40006
#define ID_VIEW_SETTINGS 40007
#define ID_VIEW_RESET 40008
#define ID_OBJECT_LOAD 40009
#define ID_OBJECT_SAVE 40010
#define ID_ABOUT 40011
#define ID_FILE_CLOSE 40013
#define ID_BACKUP_SAVE 40014
#define ID_BACKUP_RESTORE 40015
#define ID_BACKUP_DELETE 40016
#define ID_VIEW_SCRIPT 40017
#define ID_HELP_REGISTER 40018
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 112
#define _APS_NEXT_COMMAND_VALUE 40019
#define _APS_NEXT_CONTROL_VALUE 1027
#define _APS_NEXT_SYMED_VALUE 108
#endif
#endif

View file

@ -1,208 +0,0 @@
/*
* timer.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
BOOL bAccurateTimer = TRUE;
UINT uT1Period = 62;
static BOOL bStarted = FALSE;
static UINT uT1TimerId = 0;
static UINT uT2TimerId = 0;
static DWORD dwT1Ticks = 0;
static DWORD dwT2Init = 0;
static DWORD dwT2Step = 0;
static DWORD dwT2Ticks = 0;
static __inline MAX(int a, int b) {return (a>b)?a:b;}
static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
static VOID CheckT1()
{
_ASSERT(bStarted);
if ((Chipset.t1&8) == 0)
{
Chipset.IORam[0x2E] &= 0x7; // clear bit 3
return;
}
if (Chipset.IORam[0x2E]&4)
{ // T1 -> Wake Up
if (Chipset.Shutdn)
{
ResumeThread(hThread);
Chipset.IORam[0x2E] &= 0xB; // clear bit 2
Chipset.IORam[0x2E] |= 0x8; // set bit 3
}
}
if (Chipset.IORam[0x2E]&2)
{ // T1 -> Interrupt
Chipset.IORam[0x2E] |= 0x8; // set bit 3
Chipset.SoftInt = TRUE;
bInterrupt=TRUE;
}
return;
}
static VOID CheckT2()
{
_ASSERT(bStarted);
if ((Chipset.t2&0x80000000) == 0)
{
Chipset.IORam[0x2F] &= 7; // clear bit 3
return;
}
if (Chipset.IORam[0x2F]&4)
{ // T2 -> Wake Up
if (Chipset.Shutdn)
{
ResumeThread(hThread);
Chipset.IORam[0x2F] &= 0xB; // clear bit 2
Chipset.IORam[0x2F] |= 0x8; // set bit 3
}
}
if (Chipset.IORam[0x2F]&2)
{ // T2 -> Interrupt
Chipset.IORam[0x2F] |= 0x8; // set bit 3
Chipset.SoftInt = TRUE;
bInterrupt=TRUE;
}
return;
}
static VOID RescheduleT2()
{
_ASSERT(uT2TimerId == 0);
dwT2Init = timeGetTime();
dwT2Ticks = dwT2Init;
uT2TimerId = timeSetEvent(MAX(16,Chipset.t2>>3),0,(LPTIMECALLBACK)&TimeProc,2,TIME_ONESHOT);
return;
}
static VOID AbortT2()
{
_ASSERT(uT2TimerId != 0);
uT2TimerId = 0;
timeKillEvent(uT2TimerId);
return;
}
static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
if (!bStarted)
return;
if ((uT1TimerId!=0) && (uEventId == uT1TimerId))
{
Chipset.t1 = (Chipset.t1-1)&0xF;
CheckT1();
return;
}
if ((uT2TimerId!=0) && (uEventId == uT2TimerId))
{
uT2TimerId = 0;
Chipset.t2 = 0xFFFFFFFF;
CheckT2();
RescheduleT2();
return;
}
return;
UNREFERENCED_PARAMETER(uMsg);
}
VOID StartTimers()
{
if (bStarted)
return;
if (Chipset.IORam[0x2F]&1)
{
bStarted = TRUE;
if (bAccurateTimer)
{
MMRESULT uResult;
uResult = timeBeginPeriod(1);
if (uResult!=TIMERR_NOERROR)
bAccurateTimer=FALSE;
}
uT1TimerId = timeSetEvent(uT1Period,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC);
RescheduleT2();
}
return;
}
VOID StopTimers()
{
if (!bStarted)
return;
Chipset.t2 = ReadT2();
if (uT1TimerId != 0)
{
timeKillEvent(uT1TimerId);
uT1TimerId = 0;
}
if (uT2TimerId != 0)
AbortT2();
bStarted = FALSE;
if (bAccurateTimer)
{
timeEndPeriod(1);
}
return;
}
DWORD ReadT2()
{
DWORD dwT2;
if (!bStarted)
{
dwT2 = Chipset.t2;
}
else
{
DWORD dwNow = timeGetTime();
if (dwNow == dwT2Ticks)
{
if (dwT2Step < 7)
dwT2Step++;
return Chipset.t2-(8*(dwNow-dwT2Init)+dwT2Step);
}
dwT2Step = 0;
dwT2Ticks = dwNow;
dwT2 = Chipset.t2-8*(dwNow-dwT2Init);
}
return dwT2;
}
VOID SetT2(DWORD dwValue)
{
if (!bStarted)
{
Chipset.t2 = dwValue;
return;
}
if (uT2TimerId != 0)
AbortT2();
Chipset.t2 = dwValue;
CheckT2();
RescheduleT2();
return;
}
BYTE ReadT1()
{
return Chipset.t1;
}
VOID SetT1(BYTE byValue)
{
Chipset.t1 = byValue&0xF;
CheckT1();
return;
}

View file

@ -1,87 +0,0 @@
/*
* types.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#define CHIPSET Chipset_t
typedef struct
{
WORD wPosX;
WORD wPosY;
BYTE type;
DWORD Port0Size;
DWORD Port1Size;
DWORD Port2Size;
LPBYTE Port0;
LPBYTE Port1;
LPBYTE Port2;
DWORD pc;
DWORD d0;
DWORD d1;
DWORD rstkp;
DWORD rstk[8];
BYTE A[16];
BYTE B[16];
BYTE C[16];
BYTE D[16];
BYTE R0[16];
BYTE R1[16];
BYTE R2[16];
BYTE R3[16];
BYTE R4[16];
BYTE ST[4];
BYTE HST;
BYTE P;
WORD out;
WORD in;
BOOL SoftInt;
BOOL Shutdn;
BOOL mode_dec;
BOOL inte;
BOOL intk;
BOOL intd;
BOOL carry;
WORD crc;
UINT uUnused1;
UINT Port2_Size;
BOOL Port1_Writeable;
BOOL Port2_Writeable;
UINT Port2_Bank;
UINT Port2_NBanks;
BYTE cards_status;
BYTE IORam[64];
UINT IOBase;
BOOL IOCfig;
BYTE P0Base, BSBase, P1Base, P2Base;
BYTE P0Size, BSSize, P1Size, P2Size;
BYTE P0End, BSEnd, P1End, P2End;
BOOL P0Cfig, BSCfig, P1Cfig, P2Cfig;
BOOL P0Cfg2, BSCfg2, P1Cfg2, P2Cfg2;
BYTE t1;
DWORD t2;
DWORD t2_ticks;
BYTE Keyboard_Row[9];
WORD IR15X;
UINT Keyboard_State;
signed short loffset;
signed int width;
UINT boffset;
UINT lcounter;
UINT sync;
BYTE contrast;
BOOL dispon;
DWORD start1;
DWORD start12;
DWORD end1;
DWORD start2, end2;
} Chipset_t;

BIN
FLOAT_GX.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

401
FLOAT_GX.KML Normal file
View file

@ -0,0 +1,401 @@
Global
Print "=========================================================="
Print ""
Print "This graphic is by Casey Patterson."
Print "pattersc@gulftel.com"
Print ""
Print "Come to my page to get more graphics for your Win48!!!"
Print ""
Print "http://www.gulftel.com/~pattersc/win48/"
Print ""
Print "=========================================================="
Title "Floating Buttons for GX"
Author "Casey Patterson"
Model "G"
Rom "ROM.48G"
Patch "BEEP.EXT"
Debug 0
Bitmap "float_gx.bmp"
End
Background
Offset 0 0
Size 302 485
End
Lcd
Zoom 2
Offset 20 20
Color 0 255 255 255
Color 1 0 0 0
Color 2 0 0 0
Color 3 0 0 0
Color 4 0 0 0
Color 5 0 0 0
Color 6 0 0 0
Color 8 0 0 0
Color 9 0 0 0
Color 10 0 0 0
Color 11 0 0 0
Color 12 0 0 0
Color 13 0 0 0
Color 14 0 0 0
Color 15 0 0 0
Color 16 0 0 0
Color 17 0 0 0
Color 18 0 0 0
Color 19 0 0 0
Color 20 0 0 0
Color 21 0 0 0
Color 22 0 0 0
Color 23 0 0 0
Color 24 0 0 0
Color 25 0 0 0
Color 26 0 0 0
Color 27 0 0 0
Color 28 0 0 0
Color 29 0 0 0
Color 30 0 0 0
Color 31 0 0 0
End
Annunciator 1
Size 15 11
Offset 41 4
Down 16 485
End
Annunciator 2
Size 15 11
Offset 82 4
Down 32 485
End
Annunciator 3
Size 13 11
Offset 123 4
Down 48 485
End
Annunciator 4
Size 15 11
Offset 164 4
Down 64 485
End
Annunciator 5
Size 11 11
Offset 205 4
Down 80 485
End
Annunciator 6
Size 12 11
Offset 246 4
Down 96 485
End
Button 11
Size 38 27
Offset 8 158
Down 6 156
OutIn 1 16
End
Button 12
Size 38 27
Offset 58 158
Down 56 156
OutIn 8 16
End
Button 13
Size 38 27
Offset 108 158
Down 106 156
OutIn 8 8
End
Button 14
Size 38 27
Offset 158 158
Down 156 156
OutIn 8 4
End
Button 15
Size 38 27
Offset 208 158
Down 206 156
OutIn 8 2
End
Button 16
Size 38 27
Offset 258 158
Down 256 156
OutIn 8 1
End
Button 21
Size 38 27
Offset 8 195
Down 6 193
OutIn 2 16
End
Button 22
Size 38 27
Offset 58 195
Down 56 193
OutIn 7 16
End
Button 23
Size 38 27
Offset 108 195
Down 106 193
OutIn 7 8
End
Button 24
Size 38 27
Offset 158 195
Down 156 193
OutIn 7 4
End
Button 25
Size 38 27
Offset 208 195
Down 206 193
OutIn 7 2
End
Button 26
Size 38 27
Offset 258 195
Down 256 193
OutIn 7 1
End
Button 31
Size 38 27
Offset 8 232
Down 6 230
OutIn 0 16
End
Button 32
Size 38 27
Offset 58 232
Down 56 230
OutIn 6 16
End
Button 33
Size 38 27
Offset 108 232
Down 106 230
OutIn 6 8
End
Button 34
Size 38 27
Offset 158 232
Down 156 230
OutIn 6 4
End
Button 35
Size 38 27
Offset 208 232
Down 206 230
OutIn 6 2
End
Button 36
Size 38 27
Offset 258 232
Down 256 230
OutIn 6 1
End
Button 41
Size 38 27
Offset 8 269
Down 6 267
OutIn 3 16
End
Button 42
Size 38 27
Offset 58 269
Down 56 267
OutIn 5 16
End
Button 43
Size 38 27
Offset 108 269
Down 106 267
OutIn 5 8
End
Button 44
Size 38 27
Offset 158 269
Down 156 267
OutIn 5 4
End
Button 45
Size 38 27
Offset 208 269
Down 206 267
OutIn 5 2
End
Button 46
Size 38 27
Offset 258 269
Down 256 267
OutIn 5 1
End
Button 51
Size 88 27
Offset 8 306
Down 6 304
OutIn 4 16
End
Button 52
Size 38 27
Offset 108 306
Down 106 304
OutIn 4 8
End
Button 53
Size 38 27
Offset 158 306
Down 156 304
OutIn 4 4
End
Button 54
Size 38 27
Offset 208 306
Down 206 304
OutIn 4 2
End
Button 55
Size 38 27
Offset 258 306
Down 256 304
OutIn 4 1
End
Button 61
Size 38 27
Offset 8 343
Down 6 341
OutIn 3 32
End
Button 62
Size 49 27
Offset 67 343
Down 65 341
OutIn 3 8
End
Button 63
Size 49 27
Offset 127 343
Down 125 341
OutIn 3 4
End
Button 64
Size 49 27
Offset 187 343
Down 185 341
OutIn 3 2
End
Button 65
Size 49 27
Offset 247 343
Down 245 341
OutIn 3 1
End
Button 71
Size 36 25
Offset 8 380
Down 6 378
OutIn 2 32
End
Button 72
Size 49 27
Offset 67 380
Down 65 378
OutIn 2 8
End
Button 73
Size 49 27
Offset 127 380
Down 125 378
OutIn 2 4
End
Button 74
Size 49 27
Offset 187 380
Down 185 378
OutIn 2 2
End
Button 75
Size 49 27
Offset 247 380
Down 245 378
OutIn 2 1
End
Button 81
Size 36 25
Offset 8 417
Down 6 415
OutIn 1 32
End
Button 82
Size 49 27
Offset 67 417
Down 65 415
OutIn 1 8
End
Button 83
Size 49 27
Offset 127 417
Down 125 415
OutIn 1 4
End
Button 84
Size 49 27
Offset 187 417
Down 185 415
OutIn 1 2
End
Button 85
Size 49 27
Offset 247 417
Down 245 415
OutIn 1 1
End
Button 91
Size 38 27
Offset 8 454
Down 6 452
OutIn 0 32768
End
Button 92
Size 49 27
Offset 67 454
Down 65 451
OutIn 0 8
End
Button 93
Size 49 27
Offset 127 454
Down 125 452
OutIn 0 4
End
Button 94
Size 49 27
Offset 187 454
Down 185 452
OutIn 0 2
End
Button 95
Size 49 27
Offset 247 454
Down 245 452
OutIn 0 1
End
Include "Keyboard.kmi"

BIN
JC.BMP Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

364
JC.KML Normal file
View file

@ -0,0 +1,364 @@
Global
Title "Small but realistic HP48 Gx"
Author "Jeffery L. McMahan and Sebastien Carlier"
Print "Original picture by Jeffery L. McMahan"
Print "Modified for VGA by Sebastien Carlier"
Model "G"
Rom "ROM.48G"
Patch "BEEP.EXT"
Bitmap "jc.bmp"
Debug 1
End
Background
Offset 0 0
Size 165 353
End
Lcd
Zoom 1
Offset 17 43
Include "TrueLCD.kmi"
End
Annunciator 1
Size 8 6
Offset 40 45
Down 0 400
End
Annunciator 2
Size 8 6
Offset 60 45
Down 9 400
End
Annunciator 3
Size 8 6
Offset 80 45
Down 17 400
End
Annunciator 4
Size 10 6
Offset 100 45
Down 25 400
End
Annunciator 5
Size 5 6
Offset 120 45
Down 35 400
End
Annunciator 6
Size 7 6
Offset 140 45
Down 43 400
End
Button 11
Type 3
Size 16 10
Offset 17 139
OutIn 1 16
End
Button 12
Type 3
Size 16 10
Offset 40 139
OutIn 8 16
End
Button 13
Type 3
Size 16 10
Offset 63 139
OutIn 8 8
End
Button 14
Type 3
Size 16 10
Offset 86 139
OutIn 8 4
End
Button 15
Type 3
Size 16 10
Offset 109 139
OutIn 8 2
End
Button 16
Type 3
Size 16 10
Offset 132 139
OutIn 8 1
End
Button 21
Type 3
Size 16 12
Offset 17 162
OutIn 2 16
End
Button 22
Type 3
Size 16 12
Offset 40 162
OutIn 7 16
End
Button 23
Type 3
Size 16 12
Offset 63 162
OutIn 7 8
End
Button 24
Type 3
Size 16 12
Offset 86 162
OutIn 7 4
End
Button 25
Type 3
Size 16 12
Offset 109 162
OutIn 7 2
End
Button 26
Type 3
Size 16 12
Offset 132 162
OutIn 7 1
End
Button 31
Type 3
Size 16 12
Offset 17 184
OutIn 0 16
End
Button 32
Type 3
Size 16 12
Offset 40 184
OutIn 6 16
End
Button 33
Type 3
Size 16 12
Offset 63 184
OutIn 6 8
End
Button 34
Type 3
Size 16 12
Offset 86 184
OutIn 6 4
End
Button 35
Type 3
Size 16 12
Offset 109 184
OutIn 6 2
End
Button 36
Type 3
Size 16 12
Offset 132 184
OutIn 6 1
End
Button 41
Type 3
Size 16 12
Offset 17 207
OutIn 3 16
End
Button 42
Type 3
Size 16 12
Offset 40 207
OutIn 5 16
End
Button 43
Type 3
Size 16 12
Offset 63 207
OutIn 5 8
End
Button 44
Type 3
Size 16 12
Offset 86 207
OutIn 5 4
End
Button 45
Type 3
Size 16 12
Offset 109 207
OutIn 5 2
End
Button 46
Type 3
Size 16 12
Offset 132 207
OutIn 5 1
End
Button 51
Type 1
Size 39 12
Offset 17 229
OutIn 4 16
End
Button 52
Type 3
Size 16 10
Offset 70 229
OutIn 4 8
End
Button 53
Type 3
Size 16 10
Offset 95 229
OutIn 4 4
End
Button 54
Type 3
Size 16 10
Offset 121 229
OutIn 4 2
End
Button 55
Type 3
Size 16 10
Offset 147 229
OutIn 4 1
End
Button 61
Type 3
Size 16 10
Offset 19 252
OutIn 3 32
End
Button 62
Type 3
Size 21 12
Offset 43 252
OutIn 3 8
End
Button 63
Type 3
Size 21 12
Offset 79 252
OutIn 3 4
End
Button 64
Type 3
Size 21 12
Offset 110 252
OutIn 3 2
End
Button 65
Type 3
Size 21 12
Offset 141 252
OutIn 3 1
End
Button 71
Type 3
Size 16 10
Offset 19 274
OutIn 2 32
End
Button 72
Type 3
Size 21 12
Offset 48 274
OutIn 2 8
End
Button 73
Type 3
Size 21 12
Offset 79 274
OutIn 2 4
End
Button 74
Type 3
Size 21 12
Offset 110 274
OutIn 2 2
End
Button 75
Type 3
Size 21 12
Offset 141 274
OutIn 2 1
End
Button 81
Type 3
Size 16 10
Offset 19 297
OutIn 1 32
End
Button 82
Type 3
Size 21 12
Offset 48 297
OutIn 1 8
End
Button 83
Type 3
Size 21 12
Offset 79 297
OutIn 1 4
End
Button 84
Type 3
Size 21 12
Offset 110 297
OutIn 1 2
End
Button 85
Type 3
Size 21 12
Offset 141 297
OutIn 1 1
End
Button 91
Type 3
Size 16 10
Offset 19 319
OutIn 0 32768
End
Button 92
Type 3
Size 21 12
Offset 48 319
OutIn 0 8
End
Button 93
Type 3
Size 21 12
Offset 79 319
OutIn 0 4
End
Button 94
Type 3
Size 21 12
Offset 110 319
OutIn 0 2
End
Button 95
Type 3
Size 21 12
Offset 141 319
OutIn 0 1
End
Include "Keyboard.kmi"

710
JEMAC.KML Normal file
View file

@ -0,0 +1,710 @@
Global
Title "Jemac's Gx"
Author "Jeffery L. McMahan"
Model "G"
Rom "ROM.48G"
Patch "BEEP.EXT"
Bitmap "jemac.bmp"
Debug 0
End
Background
Offset 0 0
Size 324 703
End
Lcd
Zoom 2
Offset 34 86
Color 0 123 132 99
Color 1 123 132 99
Color 2 123 132 99
Color 3 123 132 99
Color 4 123 132 99
Color 5 123 132 99
Color 6 123 132 99
Color 7 123 132 99
Color 8 123 132 99
Color 9 116 124 96
Color 10 109 116 93
Color 11 102 108 90
Color 12 95 100 87
Color 13 88 92 84
Color 14 81 84 78
Color 15 74 76 75
Color 16 67 68 72
Color 17 60 60 69
Color 18 53 52 66
Color 19 46 44 63
Color 20 39 36 60
Color 21 32 28 57
Color 22 25 20 54
Color 23 18 12 51
Color 24 11 4 48
Color 25 4 0 45
Color 26 0 0 42
Color 27 0 0 39
Color 28 0 0 36
Color 29 0 0 33
Color 30 0 0 30
Color 31 0 0 27
End
Annunciator 1
Size 17 12
Offset 45 74
Down 0 708
End
Annunciator 2
Size 17 12
Offset 85 74
Down 17 708
End
Annunciator 3
Size 16 12
Offset 125 74
Down 34 708
End
Annunciator 4
Size 18 12
Offset 165 74
Down 50 708
End
Annunciator 5
Size 16 12
Offset 225 74
Down 68 708
End
Annunciator 6
Size 16 12
Offset 265 74
Down 84 708
End
Button 11
Type 1
Size 32 21
Offset 34 278
OutIn 1 16
End
Button 12
Type 1
Size 32 21
Offset 80 278
OutIn 8 16
End
Button 13
Type 1
Size 32 21
Offset 126 278
OutIn 8 8
End
Button 14
Type 1
Size 32 21
Offset 172 278
OutIn 8 4
End
Button 15
Type 1
Size 32 21
Offset 218 278
OutIn 8 2
End
Button 16
Type 1
Size 32 21
Offset 264 278
OutIn 8 1
End
Button 21
Type 1
Size 32 24
Offset 34 324
OutIn 2 16
End
Button 22
Type 1
Size 32 24
Offset 80 324
OutIn 7 16
End
Button 23
Type 1
Size 32 24
Offset 126 324
OutIn 7 8
End
Button 24
Type 1
Size 32 24
Offset 172 324
OutIn 7 4
End
Button 25
Type 1
Size 32 24
Offset 218 324
OutIn 7 2
End
Button 26
Type 1
Size 32 24
Offset 264 324
OutIn 7 1
End
Button 31
Type 1
Size 32 24
Offset 34 369
OutIn 0 16
End
Button 32
Type 1
Size 32 24
Offset 80 369
OutIn 6 16
End
Button 33
Type 1
Size 32 24
Offset 126 369
OutIn 6 8
End
Button 34
Type 1
Size 32 24
Offset 172 369
OutIn 6 4
End
Button 35
Type 1
Size 32 24
Offset 218 369
OutIn 6 2
End
Button 36
Type 1
Size 32 24
Offset 264 369
OutIn 6 1
End
Button 41
Type 1
Size 32 24
Offset 34 414
OutIn 3 16
End
Button 42
Type 1
Size 32 24
Offset 80 414
OutIn 5 16
End
Button 43
Type 1
Size 32 24
Offset 126 414
OutIn 5 8
End
Button 44
Type 1
Size 32 24
Offset 172 414
OutIn 5 4
End
Button 45
Type 1
Size 32 24
Offset 218 414
OutIn 5 2
End
Button 46
Type 1
Size 32 24
Offset 264 414
OutIn 5 1
End
Button 51
Type 1
Size 77 24
Offset 34 459
OutIn 4 16
End
Button 52
Type 1
Size 32 24
Offset 126 459
OutIn 4 8
End
Button 53
Type 1
Size 32 24
Offset 172 459
OutIn 4 4
End
Button 54
Type 1
Size 32 24
Offset 218 459
OutIn 4 2
End
Button 55
Type 1
Size 32 24
Offset 264 459
OutIn 4 1
End
Button 61
Type 1
Size 32 24
Offset 34 504
OutIn 3 32
End
Button 62
Type 1
Size 42 24
Offset 86 504
OutIn 3 8
End
Button 63
Type 1
Size 42 24
Offset 142 504
OutIn 3 4
End
Button 64
Type 1
Size 42 24
Offset 198 504
OutIn 3 2
End
Button 65
Type 1
Size 42 24
Offset 254 504
OutIn 3 1
End
Button 71
Type 1
Size 32 24
Offset 34 549
OutIn 2 32
End
Button 72
Type 1
Size 42 24
Offset 86 549
OutIn 2 8
End
Button 73
Type 1
Size 42 24
Offset 142 549
OutIn 2 4
End
Button 74
Type 1
Size 42 24
Offset 198 549
OutIn 2 2
End
Button 75
Type 1
Size 42 24
Offset 254 549
OutIn 2 1
End
Button 81
Type 1
Size 32 24
Offset 34 594
OutIn 1 32
End
Button 82
Type 1
Size 42 24
Offset 86 594
OutIn 1 8
End
Button 83
Type 1
Size 42 24
Offset 142 594
OutIn 1 4
End
Button 84
Type 1
Size 42 24
Offset 198 594
OutIn 1 2
End
Button 85
Type 1
Size 42 24
Offset 254 594
OutIn 1 1
End
Button 91
Type 1
Size 32 24
Offset 34 639
OutIn 0 32768
End
Button 92
Type 1
Size 42 24
Offset 86 639
OutIn 0 8
End
Button 93
Type 1
Size 42 24
Offset 142 639
OutIn 0 4
End
Button 94
Type 1
Size 42 24
Offset 198 639
OutIn 0 2
End
Button 95
Type 1
Size 42 24
Offset 254 639
OutIn 0 1
End
Scancode 8
Map 8 55
End
Scancode 13
Map 13 51
End
Scancode 16
IfPressed 16
SetFlag 0
Else
ResetFlag 0
End
End
Scancode 17
IfPressed 17
SetFlag 1
Else
ResetFlag 1
End
End
Scancode 27
Map 27 91
End
Scancode 32
Map 32 94
End
Scancode 37
Map 37 34
End
Scancode 38
Map 38 25
End
Scancode 39
Map 39 36
End
Scancode 40
Map 40 35
End
Scancode 49
IfFlag 0
Map 49 71
Map 49 54
Else
Map 49 82
End
End
Scancode 50
Map 50 83
End
Scancode 51
IfFlag 0
Map 51 81
Map 51 65
Else
Map 51 84
End
End
Scancode 52
Map 52 72
End
Scancode 53
Map 53 73
End
Scancode 54
Map 54 74
End
Scancode 55
Map 55 62
End
Scancode 56
IfFlag 0
Map 56 75
Else
Map 56 63
End
End
Scancode 57
IfFlag 0
Map 57 71
Map 57 65
Else
Map 57 64
End
End
Scancode 65
Map 65 11
End
Scancode 66
Map 66 12
End
Scancode 67
Map 67 13
End
Scancode 68
Map 68 14
End
Scancode 69
Map 69 15
End
Scancode 70
Map 70 16
End
Scancode 71
Map 71 21
End
Scancode 72
Map 72 22
End
Scancode 73
Map 73 23
End
Scancode 74
Map 74 24
End
Scancode 75
Map 75 25
End
Scancode 76
Map 76 26
End
Scancode 77
Map 77 31
End
Scancode 78
IfFlag 1
MenuItem 1
Else
Map 78 32
End
End
Scancode 79
Map 79 33
End
Scancode 80
Map 80 34
End
Scancode 81
Map 81 35
End
Scancode 82
Map 82 36
End
Scancode 83
Map 83 41
End
Scancode 84
Map 84 42
End
Scancode 85
Map 85 43
End
Scancode 86
Map 86 44
End
Scancode 87
Map 87 45
End
Scancode 88
Map 88 46
End
Scancode 89
Map 89 52
End
Scancode 90
Map 90 53
End
Scancode 96
Map 96 92
End
Scancode 97
Map 97 82
End
Scancode 98
Map 98 83
End
Scancode 99
Map 99 84
End
Scancode 100
Map 100 72
End
Scancode 101
Map 101 73
End
Scancode 102
Map 102 74
End
Scancode 103
Map 103 62
End
Scancode 104
Map 104 63
End
Scancode 105
Map 105 64
End
Scancode 106
Map 106 75
End
Scancode 107
Map 107 95
End
Scancode 109
Map 109 85
End
Scancode 110
Map 110 93
End
Scancode 111
Map 111 65
End
Scancode 186
IfFlag 0
Map 186 81
Map 186 95
End
End
Scancode 188
Map 188 71
Map 188 93
End
Scancode 190
Map 190 93
End
Scancode 191
IfFlag 0
Map 191 71
Map 191 55
Else
Map 191 65
End
End
Scancode 219
IfFlag 0
Map 219 71
Map 219 95
Else
Map 219 71
Map 219 75
End
End
Scancode 220
Map 220 54
End
Scancode 222
IfFlag 0
Map 222 81
Map 222 85
Else
Map 222 31
End
End

352
Keyboard.kmi Normal file
View file

@ -0,0 +1,352 @@
Scancode 8
Map 8 55
End
Scancode 13
Map 13 51
End
Scancode 16
IfPressed 16
SetFlag 0
Else
ResetFlag 0
End
End
Scancode 17
IfPressed 17
SetFlag 1
Else
ResetFlag 1
End
End
Scancode 27
Map 27 91
End
Scancode 32
Map 32 94
End
Scancode 37
Map 37 34
End
Scancode 38
Map 38 25
End
Scancode 39
Map 39 36
End
Scancode 40
Map 40 35
End
Scancode 48
Map 48 92
End
Scancode 49
IfFlag 0
Map 49 71
Map 49 54
Else
Map 49 82
End
End
Scancode 50
Map 50 83
End
Scancode 51
IfFlag 0
Map 51 81
Map 51 65
Else
Map 51 84
End
End
Scancode 52
Map 52 72
End
Scancode 53
Map 53 73
End
Scancode 54
Map 54 74
End
Scancode 55
Map 55 62
End
Scancode 56
IfFlag 0
Map 56 75
Else
Map 56 63
End
End
Scancode 57
IfFlag 0
Map 57 71
Map 57 65
Else
Map 57 64
End
End
Scancode 65
Map 65 11
End
Scancode 66
Map 66 12
End
Scancode 67
Map 67 13
End
Scancode 68
Map 68 14
End
Scancode 69
Map 69 15
End
Scancode 70
Map 70 16
End
Scancode 71
Map 71 21
End
Scancode 72
Map 72 22
End
Scancode 73
Map 73 23
End
Scancode 74
Map 74 24
End
Scancode 75
Map 75 25
End
Scancode 76
Map 76 26
End
Scancode 77
Map 77 31
End
Scancode 78
IfFlag 1
MenuItem 1
Else
Map 78 32
End
End
Scancode 79
Map 79 33
End
Scancode 80
Map 80 34
End
Scancode 81
Map 81 35
End
Scancode 82
Map 82 36
End
Scancode 83
Map 83 41
End
Scancode 84
Map 84 42
End
Scancode 85
Map 85 43
End
Scancode 86
Map 86 44
End
Scancode 87
Map 87 45
End
Scancode 88
Map 88 46
End
Scancode 89
Map 89 52
End
Scancode 90
Map 90 53
End
Scancode 96
Map 96 92
End
Scancode 97
Map 97 82
End
Scancode 98
Map 98 83
End
Scancode 99
Map 99 84
End
Scancode 100
Map 100 72
End
Scancode 101
Map 101 73
End
Scancode 102
Map 102 74
End
Scancode 103
Map 103 62
End
Scancode 104
Map 104 63
End
Scancode 105
Map 105 64
End
Scancode 106
Map 106 75
End
Scancode 107
Map 107 95
End
Scancode 109
Map 109 85
End
Scancode 110
Map 110 93
End
Scancode 111
Map 111 65
End
Scancode 144
IfPressed 144
NotFlag 3
End
End
Scancode 186
IfFlag 0
Map 186 81
Map 186 95
End
End
Scancode 188
IfFlag 0
Map 188 71
Else
Map 188 71
Map 188 93
End
End
Scancode 190
IfFlag 0
Map 190 81
Else
Map 190 93
End
End
Scancode 191
IfFlag 0
Map 191 71
Map 191 55
Else
Map 191 65
End
End
Scancode 192
IfFlag 0
IfPressed 192
NotFlag 2
IfFlag 2
Press 61
Else
Release 61
End
End
Else
Map 192 61
End
End
Scancode 219
IfFlag 0
Map 219 71
Map 219 95
Else
Map 219 71
Map 219 75
End
End
Scancode 220
Map 220 54
End
Scancode 222
IfFlag 0
Map 222 81
Map 222 85
Else
Map 222 31
End
End

BIN
MkShared.exe Normal file

Binary file not shown.

37
PROBLEMS.TXT Normal file
View file

@ -0,0 +1,37 @@
Known bugs and restrictions of Emu48 V1.10
------------------------------------------
- input cursor blink frequency on stack view is wrong when a key is
hold down
- the POWERCTRL register (0x109) isn't emulated
- bit 3 [UCK] of the BAUD register (0x10D) isn't emulated
- the bits of the SRQ registers (0x118,0x119), except the KDN bit,
aren't emulated
- the baudrates 1920, 3840, 7680 and 15360 aren't emulated on most
operating systems
Windows 95a 1920, 3840, 7680 work, 15360 fail
Windows 98 all baudrates fail
Windows NT4.0 SP3 all baudrates fail
- System-RPL commands VERYVERYSLOW, VERYSLOW and SLOW depends on PC
speed (are realized as simple down counter in ROM)
- in all original KML scripts Color 7 is missing in the LCD section
- because of correcting the RGB order in SetLcdColor() the LCD
background color may be wrong in some KML scripts
- display updating differs from the real machine
- screen VBL counter values may skip after large display operations
like turning on or updating the whole display
- read on an unconfigured address (open data bus) will not show the
same value like a real calculator
- the G(X) hardware signals BEN and DA19 aren't fully supported,
because the emulator don't use a multiplexed AR18 / NCE3 data line
-> all programs that run on a real calculator will run as well,
programs with incorrect DA19 / BEN handling may run on the
emulator and will crash on a real calculator
- no beeper support with OUT command -> all programs that aren't
use the "=makebeep" subroutine, like alarm wake up, have no sound
- beeper emulation, ATTN key doesn't work,
Windows 9x: plays only default sound event or standard system beep
- no infrared printer support
- Shell OS: clock isn't synchronized with real time
03/11/99 (c) by Christoph Gießelink, cgiess@swol.de

BIN
ROMDUMP.EXE Normal file

Binary file not shown.

27
ROMDUMP.TXT Normal file
View file

@ -0,0 +1,27 @@
########################################
# #
# ROMDump Wizard #
# #
########################################
This program is a rewritten version of the ROMDump Wizard from
Sebastien Carlier. It based on API calls and doesn't need the
MFC DLL's any more. It has been written to allow you to quickly
dump the rom from your HP48. The process is entirely automated,
and should work most of the time. However, I cannot guarantee
that it will work on your computer. It works perfectly on my
computer.
My ROM copy times:
SX: 00:16:10 (OS: NT4.0 SP3)
SX: 00:15:38 (OS: Win95 4.00.950a)
GX: 00:30:47 (OS: Win95 4.00.950a)
After download you will find the rom file ROM.48S or ROM.48G in
the directory of the ROMDUMP.EXE utility. Be sure that there is
no older file with the used names in this directory before using!
If you have any problems, please don't ask me. I'm busy enough
with my work.
-- Christoph Gießelink

View file

@ -1,83 +0,0 @@
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "ROMDump.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMainFrame constructor
CMainFrame::CMainFrame(HICON icon)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
Create(AfxRegisterWndClass(0,0,0,icon),"ROMDump Wizard",WS_MAXIMIZE|WS_OVERLAPPEDWINDOW,rectDefault,NULL,NULL,0,NULL);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CFrameWnd::PreCreateWindow(cs);
}
void CMainFrame::DoDataExchange(CDataExchange* pDX)
{
CFrameWnd::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rect;
DWORD dy, y;
int i;
GetClientRect(&rect);
dy = rect.bottom<<8;
for (i=0,y=0; i<256; i++)
{
CBrush brush(i<<16);
rect.top = y>>16;
y += dy;
rect.bottom = y>>16;
if (rect.top!=rect.bottom) dc.FillRect(&rect, &brush);
}
{
CFont font, *o_font;
CBrush brush(0xFFFFFF);
font.CreateFont(72,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,OUT_DEVICE_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH|TMPF_TRUETYPE|FF_ROMAN,"Times New Roman");
o_font = dc.SelectObject(&font);
GetClientRect(&rect);
dc.SetBkMode(TRANSPARENT);
dc.BeginPath();
dc.TextOut(10,0,"ROMDump Wizard");
dc.EndPath();
dc.SelectClipPath(RGN_AND);
dc.FillRect(&rect,&brush);
dc.SelectObject(o_font);
}
}

View file

@ -1,31 +0,0 @@
// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////
class CMainFrame : public CFrameWnd
{
public:
CMainFrame(HICON icon); // window constructor
// Frame Data
//{{AFX_DATA(CMainFrame)
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainFrame)
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void DoDataExchange(CDataExchange* pDX);
//}}AFX_VIRTUAL
// Generated message map functions
protected:
//{{AFX_MSG(CMainFrame)
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,13 +0,0 @@
//
// ROMDUMP.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////

View file

@ -1,43 +0,0 @@
// ROMDump.h : main header file for the ROMDUMP application
//
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h" // main symbols
#define HP48S 0
#define HP48G 1
extern int Port;
extern int Type;
/////////////////////////////////////////////////////////////////////////////
// CROMDumpApp:
// See ROMDump.cpp for the implementation of this class
//
class CROMDumpApp : public CWinApp
{
public:
CROMDumpApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CROMDumpApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CROMDumpApp)
afx_msg void OnAppAbout();
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////

View file

@ -1,239 +0,0 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 12, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif\r\n"
"#include ""res\\ROMDump.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""l.fra\\afxres.rc"" // Standard components\r\n"
"#endif\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\ROMDump.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 241, 50
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER |
DS_CENTERMOUSE | WS_CHILD | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "About ROMDump Wizard"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,14,18,20
LTEXT "ROMDump Wizard version 0.2",IDC_STATIC,39,12,155,8,
SS_NOPREFIX
LTEXT "Copyright © 1996,1997 Sebastien Carlier",IDC_STATIC,39,
28,155,8
DEFPUSHBUTTON "OK",IDOK,202,29,32,14,WS_GROUP
END
IDD_STEP1 DIALOGEX 0, 0, 208, 226
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ROMDump Wizard - Step 1"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
DEFPUSHBUTTON "&Ok",IDOK,7,205,50,14
PUSHBUTTON "&Cancel",IDCANCEL,79,205,50,14
PUSHBUTTON "&Help",IDHELP,151,205,50,14
CONTROL "COM&1",IDC_PORT1,"Button",BS_AUTORADIOBUTTON | WS_GROUP |
WS_TABSTOP,45,67,36,10
CONTROL "COM&2",IDC_PORT2,"Button",BS_AUTORADIOBUTTON,104,67,36,
10
CONTROL "COM&3",IDC_PORT3,"Button",BS_AUTORADIOBUTTON,45,82,36,
10
CONTROL "COM&4",IDC_PORT4,"Button",BS_AUTORADIOBUTTON,104,81,36,
10
CTEXT "Select the port to which you HP48 is connected :",
IDC_STATIC,7,53,194,8
CONTROL 132,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE,14,
116,179,82,WS_EX_DLGMODALFRAME
CTEXT "Then check the IO parameters of your HP48 :",IDC_STATIC,
7,103,194,8
LTEXT "The ROMDump Wizard will help you to dump the content of your HP48's ROM. This process is very difficult for most users, so I hope this Wizard will save you some time. Please be patient while it is getting the ROM, it might take as much as an hour.",
IDC_STATIC,7,7,194,42,SS_SUNKEN
END
IDD_STEP2 DIALOG DISCARDABLE 0, 0, 186, 66
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "ROMDump Wizard - Step 2"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,68,45,50,14
PUSHBUTTON "OK",IDOK,7,45,50,14,WS_DISABLED
PUSHBUTTON "&Help",IDHELP,129,45,50,14
CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,
23,172,14
CTEXT "Preparing your HP48 to transfer the ROM :",IDC_STATE,7,
7,172,8
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
#else
FILEFLAGS 0x20L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "ROMDump Wizard\0"
VALUE "FileVersion", "0.01ß\0"
VALUE "InternalName", "ROMDUMP\0"
VALUE "LegalCopyright", "Copyright © 1996 Sébastien Carlier\0"
VALUE "OriginalFilename", "ROMDUMP.EXE\0"
VALUE "ProductName", "ROMDump Wizard\0"
VALUE "ProductVersion", "0.01ß\0"
VALUE "SpecialBuild", "Evaluation version\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_ABOUTBOX, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 234
TOPMARGIN, 7
BOTTOMMARGIN, 42
END
IDD_STEP1, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 201
TOPMARGIN, 7
BOTTOMMARGIN, 219
END
IDD_STEP2, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 59
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_LCD1 BITMAP DISCARDABLE "res\\lcd1.bmp"
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE 12, 1
#pragma code_page(1252)
#endif
#include "res\ROMDump.rc2" // non-Microsoft Visual C++ edited resources
#include "l.fra\afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -1,83 +0,0 @@
// ROMDump.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "ROMDump.h"
#include "MainFrm.h"
#include "About.h"
#include "Step1.h"
#include "Step2.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int Type;
/////////////////////////////////////////////////////////////////////////////
// CROMDumpApp
BEGIN_MESSAGE_MAP(CROMDumpApp, CWinApp)
//{{AFX_MSG_MAP(CROMDumpApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
// Standard file based document commands
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CROMDumpApp construction
CROMDumpApp::CROMDumpApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CROMDumpApp object
CROMDumpApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CROMDumpApp initialization
BOOL CROMDumpApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CMainFrame* pMainFrame = new CMainFrame(LoadIcon(IDR_MAINFRAME));
m_pMainWnd = pMainFrame;
pMainFrame->ShowWindow(m_nCmdShow);
pMainFrame->UpdateWindow();
CAboutDlg dlg;
dlg.Create(IDD_ABOUTBOX,m_pMainWnd);
dlg.ShowWindow(SW_SHOW);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CROMDumpApp commands
/////////////////////////////////////////////////////////////////////////////
// App command to run the dialog
void CROMDumpApp::OnAppAbout()
{
CAboutDlg aboutDlg;
aboutDlg.DoModal();
}

View file

@ -1,392 +0,0 @@
# Microsoft Developer Studio Generated NMAKE File, Format Version 40001
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
!IF "$(CFG)" == ""
CFG=ROMDump - Win32 Debug
!MESSAGE No configuration specified. Defaulting to ROMDump - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "ROMDump - Win32 Release" && "$(CFG)" !=\
"ROMDump - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Romdump.mak" CFG="ROMDump - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ROMDump - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "ROMDump - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "ROMDump - Win32 Debug"
MTL=mktyplib.exe
RSC=rc.exe
CPP=cl.exe
!IF "$(CFG)" == "ROMDump - Win32 Release"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\Romdump.exe"
CLEAN :
-@erase ".\Release\Romdump.exe"
-@erase ".\Release\About.obj"
-@erase ".\Release\Romdump.pch"
-@erase ".\Release\MainFrm.obj"
-@erase ".\Release\Serial.obj"
-@erase ".\Release\ROMDump.obj"
-@erase ".\Release\StdAfx.obj"
-@erase ".\Release\Step2.obj"
-@erase ".\Release\Step1.obj"
-@erase ".\Release\ROMDump.res"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
"_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Romdump.pch" /Yu"stdafx.h" /Fo"$(INTDIR)/"\
/c
CPP_OBJS=.\Release/
CPP_SBRS=
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /win32
MTL_PROJ=/nologo /D "NDEBUG" /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG" /d "_AFXDLL"
# ADD RSC /l 0x40c /d "NDEBUG" /d "_AFXDLL"
RSC_PROJ=/l 0x40c /fo"$(INTDIR)/ROMDump.res" /d "NDEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Romdump.bsc"
BSC32_SBRS=
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386
LINK32_FLAGS=/nologo /subsystem:windows /incremental:no\
/pdb:"$(OUTDIR)/Romdump.pdb" /machine:I386 /out:"$(OUTDIR)/Romdump.exe"
LINK32_OBJS= \
"$(INTDIR)/About.obj" \
"$(INTDIR)/MainFrm.obj" \
"$(INTDIR)/Serial.obj" \
"$(INTDIR)/ROMDump.obj" \
"$(INTDIR)/StdAfx.obj" \
"$(INTDIR)/Step2.obj" \
"$(INTDIR)/Step1.obj" \
"$(INTDIR)/ROMDump.res"
"$(OUTDIR)\Romdump.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "ROMDump - Win32 Debug"
# PROP BASE Use_MFC 6
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 6
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
OUTDIR=.\Debug
INTDIR=.\Debug
ALL : "$(OUTDIR)\Romdump.exe"
CLEAN :
-@erase ".\Debug\vc40.pdb"
-@erase ".\Debug\Romdump.pch"
-@erase ".\Debug\vc40.idb"
-@erase ".\Debug\Romdump.exe"
-@erase ".\Debug\MainFrm.obj"
-@erase ".\Debug\ROMDump.obj"
-@erase ".\Debug\Serial.obj"
-@erase ".\Debug\Step2.obj"
-@erase ".\Debug\StdAfx.obj"
-@erase ".\Debug\About.obj"
-@erase ".\Debug\Step1.obj"
-@erase ".\Debug\ROMDump.res"
-@erase ".\Debug\Romdump.ilk"
-@erase ".\Debug\Romdump.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Yu"stdafx.h" /c
CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
/D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Romdump.pch" /Yu"stdafx.h"\
/Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c
CPP_OBJS=.\Debug/
CPP_SBRS=
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /win32
MTL_PROJ=/nologo /D "_DEBUG" /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG" /d "_AFXDLL"
# ADD RSC /l 0x40c /d "_DEBUG" /d "_AFXDLL"
RSC_PROJ=/l 0x40c /fo"$(INTDIR)/ROMDump.res" /d "_DEBUG" /d "_AFXDLL"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o"$(OUTDIR)/Romdump.bsc"
BSC32_SBRS=
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386
LINK32_FLAGS=/nologo /subsystem:windows /incremental:yes\
/pdb:"$(OUTDIR)/Romdump.pdb" /debug /machine:I386 /out:"$(OUTDIR)/Romdump.exe"
LINK32_OBJS= \
"$(INTDIR)/MainFrm.obj" \
"$(INTDIR)/ROMDump.obj" \
"$(INTDIR)/Serial.obj" \
"$(INTDIR)/Step2.obj" \
"$(INTDIR)/StdAfx.obj" \
"$(INTDIR)/About.obj" \
"$(INTDIR)/Step1.obj" \
"$(INTDIR)/ROMDump.res"
"$(OUTDIR)\Romdump.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.c{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_SBRS)}.sbr:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Target
# Name "ROMDump - Win32 Release"
# Name "ROMDump - Win32 Debug"
!IF "$(CFG)" == "ROMDump - Win32 Release"
!ELSEIF "$(CFG)" == "ROMDump - Win32 Debug"
!ENDIF
################################################################################
# Begin Source File
SOURCE=.\ROMDump.cpp
DEP_CPP_ROMDU=\
".\StdAfx.h"\
".\ROMDump.h"\
".\MainFrm.h"\
".\About.h"\
".\Step1.h"\
".\Step2.h"\
"$(INTDIR)\ROMDump.obj" : $(SOURCE) $(DEP_CPP_ROMDU) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\StdAfx.cpp
DEP_CPP_STDAF=\
".\StdAfx.h"\
!IF "$(CFG)" == "ROMDump - Win32 Release"
# ADD CPP /Yc"stdafx.h"
BuildCmds= \
$(CPP) /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D\
"_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Romdump.pch" /Yc"stdafx.h" /Fo"$(INTDIR)/"\
/c $(SOURCE) \
"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
$(BuildCmds)
"$(INTDIR)\Romdump.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
$(BuildCmds)
!ELSEIF "$(CFG)" == "ROMDump - Win32 Debug"
# ADD CPP /Yc"stdafx.h"
BuildCmds= \
$(CPP) /nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\
/D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)/Romdump.pch" /Yc"stdafx.h"\
/Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c $(SOURCE) \
"$(INTDIR)\StdAfx.obj" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
$(BuildCmds)
"$(INTDIR)\Romdump.pch" : $(SOURCE) $(DEP_CPP_STDAF) "$(INTDIR)"
$(BuildCmds)
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\MainFrm.cpp
DEP_CPP_MAINF=\
".\StdAfx.h"\
".\ROMDump.h"\
".\MainFrm.h"\
"$(INTDIR)\MainFrm.obj" : $(SOURCE) $(DEP_CPP_MAINF) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\ROMDump.rc
DEP_RSC_ROMDUM=\
".\res\ROMDump.ico"\
".\res\lcd1.bmp"\
".\res\ROMDump.rc2"\
"$(INTDIR)\ROMDump.res" : $(SOURCE) $(DEP_RSC_ROMDUM) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\About.cpp
DEP_CPP_ABOUT=\
".\StdAfx.h"\
".\ROMDump.h"\
".\About.h"\
"$(INTDIR)\About.obj" : $(SOURCE) $(DEP_CPP_ABOUT) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Step1.cpp
DEP_CPP_STEP1=\
".\StdAfx.h"\
".\ROMDump.h"\
".\Step1.h"\
".\Serial.h"\
"$(INTDIR)\Step1.obj" : $(SOURCE) $(DEP_CPP_STEP1) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Step2.cpp
!IF "$(CFG)" == "ROMDump - Win32 Release"
DEP_CPP_STEP2=\
".\StdAfx.h"\
".\ROMDump.h"\
".\Step2.h"\
".\Serial.h"\
"$(INTDIR)\Step2.obj" : $(SOURCE) $(DEP_CPP_STEP2) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
!ELSEIF "$(CFG)" == "ROMDump - Win32 Debug"
DEP_CPP_STEP2=\
".\StdAfx.h"\
".\ROMDump.h"\
".\Step2.h"\
".\Serial.h"\
NODEP_CPP_STEP2=\
".\DumpRangeBin"\
"$(INTDIR)\Step2.obj" : $(SOURCE) $(DEP_CPP_STEP2) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
!ENDIF
# End Source File
################################################################################
# Begin Source File
SOURCE=.\Serial.cpp
DEP_CPP_SERIA=\
".\StdAfx.h"\
".\ROMDump.h"\
".\Serial.h"\
".\Step2.h"\
"$(INTDIR)\Serial.obj" : $(SOURCE) $(DEP_CPP_SERIA) "$(INTDIR)"\
"$(INTDIR)\Romdump.pch"
# End Source File
# End Target
# End Project
################################################################################

Binary file not shown.

View file

@ -1,6 +0,0 @@
// stdafx.cpp : source file that includes just the standard includes
// ROMDump.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View file

@ -1,58 +0,0 @@
// Step1.cpp : implementation file
//
#include "stdafx.h"
#include "romdump.h"
#include "Step1.h"
#include "Serial.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CStep1 dialog
CStep1::CStep1(CWnd* pParent /*=NULL*/)
: CDialog(CStep1::IDD, pParent)
{
//{{AFX_DATA_INIT(CStep1)
m_Port = 0;
//}}AFX_DATA_INIT
}
void CStep1::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CStep1)
DDX_Radio(pDX, IDC_PORT1, m_Port);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStep1, CDialog)
//{{AFX_MSG_MAP(CStep1)
ON_BN_CLICKED(IDC_PORT1, OnPort1)
ON_BN_CLICKED(IDC_PORT2, OnPort2)
ON_BN_CLICKED(IDC_PORT3, OnPort3)
ON_BN_CLICKED(IDC_PORT4, OnPort4)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStep1 message handlers
void CStep1::OnOK()
{
Port = m_Port + 1;
CDialog::OnOK();
}
void CStep1::OnPort1() {m_Port = 0;}
void CStep1::OnPort2() {m_Port = 1;}
void CStep1::OnPort3() {m_Port = 2;}
void CStep1::OnPort4() {m_Port = 3;}

View file

@ -1,39 +0,0 @@
// Step1.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CStep1 dialog
class CStep1 : public CDialog
{
// Construction
public:
CStep1(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CStep1)
enum { IDD = IDD_STEP1 };
int m_Port;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CStep1)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CStep1)
virtual void OnOK();
afx_msg void OnPort1();
afx_msg void OnPort2();
afx_msg void OnPort3();
afx_msg void OnPort4();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

View file

@ -1,391 +0,0 @@
//
// Serial.cpp : Serial ports operations
//
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "romdump.h"
#include "Serial.h"
#include "Step2.h" // for Progress control
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PACKET_START 1
#define PACKET_STOP 13
#define CHR(ch) (((ch)+32)&0xFF)
#define NUM(ch) ((ch)-32)
static DWORD crc1[16] =
{
0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F
};
static DWORD crc2[16] =
{
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7
};
int Port = 0;
char *sPort = "COMx";
HANDLE hCom;
BYTE pkt[1024];
BOOL SerialOpen()
{
BOOL fSuccess;
DCB dcb;
sPort[3] = Port+'0';
hCom = CreateFile(sPort,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if (hCom == INVALID_HANDLE_VALUE) return FALSE;
fSuccess = GetCommState(hCom, &dcb);
if (!fSuccess)
{
CloseHandle(hCom);
return FALSE;
}
dcb.BaudRate = 9600;
dcb.fBinary = 1;
dcb.ByteSize = 8;
dcb.Parity = 0;
dcb.StopBits = 0;
dcb.fDtrControl = 0;
dcb.fRtsControl = 0;
dcb.fOutX = 1;
dcb.fInX = 1;
fSuccess = SetCommState(hCom, &dcb);
if (!fSuccess)
{
CloseHandle(hCom);
return FALSE;
}
return TRUE;
}
void SerialClose()
{
CloseHandle(hCom);
return;
}
BYTE chk1(BYTE *pkt)
{
BYTE chk;
for (chk=0; *pkt; pkt++) chk += *pkt;
return ((chk>>6)+chk)&0x3F;
}
WORD chk3(BYTE *pkt)
{
DWORD crc;
BYTE c;
for (crc = 0; *pkt != '\0'; pkt++)
{
c = ((BYTE)crc) ^ (*pkt);
crc = (crc>>8) ^ (crc1[c>>4] ^ crc2[c&0x0F]);
}
return (WORD)crc;
}
BOOL SendPKT(BYTE type, int n, char *d)
{
DWORD len = strlen(d);
pkt[0] = PACKET_START;
pkt[1] = CHR((BYTE)len+2+(n?3:1));
pkt[2] = CHR(n);
pkt[3] = type;
strcpy((char*)(pkt+4),d);
len += 4;
pkt[len] = 0;
if (n)
{ // 16-bit CRC
WORD crc = chk3(pkt+1);
pkt[len++] = CHR((crc>>12)&0x0F);
pkt[len++] = CHR((crc>>6)&0x3F);
pkt[len++] = CHR(crc&0x3F);
}
else
{ // 6-bit chksum
pkt[len++] = CHR(chk1(pkt+1));
}
pkt[len++] = PACKET_STOP;
pkt[len] = 0;
WriteFile(hCom, pkt, len, &len, NULL);
return pkt[len];
}
BYTE RecvPKT()
{
int timeout = 10;
DWORD len;
pkt[0] = 0;
while (timeout--)
{
ReadFile(hCom, pkt, 1, &len, NULL);
if (pkt[0]==1) break; // received a packed !
if (pkt[0]=='0') ASSERT(FALSE);
}
if (!timeout) return 0;
ReadFile(hCom, pkt+1, 3, &len, NULL);
len = NUM(pkt[1])-1;
ReadFile(hCom, pkt+4, len, &len, NULL);
if (pkt[len+3]!=PACKET_STOP) return 0;
pkt[len+4] = 0;
return pkt[3];
}
char *DataPKT(char *data, DWORD *len)
{
char *p = (char*)(pkt+4), *q;
int i, n = NUM(pkt[1])-5, j, l;
for (i=0, l=0; i<n; i++)
{
if (p[i]=='#') i++;
l++;
}
data = (char*)realloc(data, *len+l+1);
q = data + *len;
*len += l;
for (i=0, j=0; i<n; i++,j++)
{
if (p[i]=='#')
{
i++;
if (p[i]=='#')
q[j] = '#';
else
q[j] = p[i]-64;
}
else
q[j] = p[i];
}
q[j] = 0;
return data;
}
char *CommandPKT(char *cmd, DWORD *len)
{
char *result = NULL;
int i;
BYTE t;
*len = 0;
l1: SendPKT('I',0,"~* @-#Y3");
t = RecvPKT();
if (t!='Y') // not ACK ?
{
if (t=='E') return NULL; // ERROR, abort
if (t=='N') goto l1; // NAK, resend
if (t==0) goto l1; // received nothing, resend
ASSERT(FALSE);
}
l2: SendPKT('C',0,cmd);
t = RecvPKT();
if (t!='S') // not an 'S' packet ?
{
if (t=='E') return NULL; // ERROR, abort
if (t=='N') goto l2; // NAK, resend
if (t==0) goto l1; // received nothing, restart
ASSERT(FALSE);
}
SendPKT('Y',0,"~& @-# 3"); // ACK
i = 1;
if (RecvPKT()!='X') return NULL;
SendPKT('Y',i++,"");
do
{
t = RecvPKT();
if (t!='D') break;
result = DataPKT(result,len);
SendPKT('Y',i++,"");
} while (i<64); // limited to 64 packets
if (t!='Z')
{
ASSERT(FALSE);
if (result) free(result);
return NULL;
}
SendPKT('Y',i++,"");
if (RecvPKT()!='B')
{
ASSERT(FALSE);
if (result) free(result);
return NULL;
}
SendPKT('Y',i++,"");
return result;
}
char *DumpRange(DWORD a, DWORD b)
{
char cmd[32];
DWORD len = 0;
char *result = NULL;
BYTE t;
wsprintf(cmd,"##%05lX ##%05lX ROMDump",a,b);
a&=0xFFFF0; // round down
b=(b+0xF)&0xFFFF0; // round up
len = ((b-a)>>4) * 24;
result = (char*)malloc(len+1);
result[len] = 0;
l1: SendPKT('I',0,"~* @-#Y3");
t = RecvPKT();
if (t!='Y') // not ACK ?
{
if (t=='E') return NULL; // ERROR, abort
if (t=='N') goto l1; // NAK, resend
if (t==0) goto l1; // received nothing, resend
ASSERT(FALSE);
}
SendPKT('C',0,cmd);
ReadFile(hCom, result, len, &len, NULL);
do t=RecvPKT(); while (t!='E');
Sleep(5);
return result;
}
__inline nib(char c) {return (c<='9')?(c-'0'):(c-'A'+10);}
BYTE *DumpRangeBin(CStep2 *dlg,DWORD a, DWORD b)
{
char buf[32];
DWORD d, c, len;
BYTE *res;
BYTE t;
wsprintf(buf,"##%05lX ##%05lX ROMDump",a,b);
dlg->m_Progress.SetRange(0,(b-a)>>4);
dlg->m_Progress.SetStep(1);
dlg->m_Progress.SetPos(0);
res = (BYTE*)malloc(b-a);
l1: SendPKT('I',0,"~* @-#Y3");
t = RecvPKT();
if (t!='Y') // not ACK ?
{
if (t=='E') return NULL; // ERROR, abort
if (t=='N') goto l1; // NAK, resend
if (t==0) goto l1; // received nothing, resend
ASSERT(FALSE);
}
SendPKT('C',0,buf);
for (d=a; d<b; d+=16)
{
ReadFile(hCom, buf, 24, &len, NULL);
c = (nib(buf[0])<<16)
| (nib(buf[1])<<12)
| (nib(buf[2])<< 8)
| (nib(buf[3])<< 4)
| (nib(buf[4]));
if (c!=d)
{
free(res);
return NULL;
}
res[d+ 0] = nib(buf[ 6]);
res[d+ 1] = nib(buf[ 7]);
res[d+ 2] = nib(buf[ 8]);
res[d+ 3] = nib(buf[ 9]);
res[d+ 4] = nib(buf[10]);
res[d+ 5] = nib(buf[11]);
res[d+ 6] = nib(buf[12]);
res[d+ 7] = nib(buf[13]);
res[d+ 8] = nib(buf[14]);
res[d+ 9] = nib(buf[15]);
res[d+10] = nib(buf[16]);
res[d+11] = nib(buf[17]);
res[d+12] = nib(buf[18]);
res[d+13] = nib(buf[19]);
res[d+14] = nib(buf[20]);
res[d+15] = nib(buf[21]);
dlg->m_Progress.StepIt();
}
do t=RecvPKT(); while (t!='E');
Sleep(5);
return res;
}
static WORD wCRC;
static WORD crc_table[16] =
{
0x0000, 0x1081, 0x2102, 0x3183, 0x4204, 0x5285, 0x6306, 0x7387,
0x8408, 0x9489, 0xA50A, 0xB58B, 0xC60C, 0xD68D, 0xE70E, 0xF78F
};
static __inline VOID CRC(BYTE nib)
{
wCRC = (WORD)((wCRC>>4)^crc_table[(wCRC^nib)&0xf]);
}
BOOL CheckROM(LPBYTE pRom, UINT uType)
{
DWORD dwD0, dwD1;
WORD wRomCRC;
UINT i;
DWORD dwBase = 0x00000;
UINT nPass = 0;
UINT nPasses;
switch (uType)
{
case HP48G:
nPasses = 2;
break;
case HP48S:
nPasses = 1;
break;
default:
return TRUE;
}
for (dwD0=0x00100; dwD0<0x00140; dwD0++) pRom[dwD0]=0;
again:
wRomCRC = pRom[dwBase+0x7FFFC]
|(pRom[dwBase+0x7FFFD]<<4)
|(pRom[dwBase+0x7FFFE]<<8)
|(pRom[dwBase+0x7FFFF]<<12);
wCRC = 0x0000;
dwD0 = dwBase + 0x00000;
dwD1 = dwBase + 0x40000;
do
{
for (i=0; i<16; i++) CRC(pRom[dwD0+i]);
for (i=0; i<16; i++) CRC(pRom[dwD1+i]);
dwD0 += 16;
dwD1 += 16;
} while (dwD0&0x3FFFF);
if (wCRC!=0xFFFF) return FALSE;
if (++nPass == nPasses) return TRUE;
dwBase += 0x80000;
goto again;
return TRUE;
}

View file

@ -1,14 +0,0 @@
extern int Port;
extern HANDLE hCom;
extern BYTE pkt[1024];
extern BOOL SerialOpen();
extern void SerialClose();
extern BOOL SendPKT(BYTE type, int n, char *d);
extern BYTE RecvPKT();
extern char *CommandPKT(char *cmd, DWORD *len);
extern char *DumpRange(DWORD a, DWORD b);
#ifdef _STEP2_
extern BYTE *DumpRangeBin(CStep2 *dlg,DWORD a, DWORD b);
#endif
extern BOOL CheckROM(LPBYTE pRom, UINT uType);

View file

@ -1,16 +0,0 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
//#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows 95 Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

View file

@ -1,226 +0,0 @@
// Step2.cpp : implementation file
//
#include "stdafx.h"
#include <memory.h>
#include "romdump.h"
#include "Step2.h"
#include "Serial.h"
#define STEPS 8+14
#define STEPIT dlg->m_Progress.StepIt()
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CStep2 dialog
CStep2::CStep2(CWnd* pParent /*=NULL*/)
: CDialog(CStep2::IDD, pParent)
{
//{{AFX_DATA_INIT(CStep2)
//}}AFX_DATA_INIT
}
void CStep2::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CStep2)
DDX_Control(pDX, IDC_STATE, m_State);
DDX_Control(pDX, IDOK, m_Ok);
DDX_Control(pDX, IDC_PROGRESS, m_Progress);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CStep2, CDialog)
//{{AFX_MSG_MAP(CStep2)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CStep2 message handlers
int CStep2::OpenError()
{
MessageBox("Fatal error:\nCannot open serial port !","ROMDump Wizard - Error",MB_ICONSTOP|MB_OK);
EndDialog(IDCANCEL);
return 0;
}
int CStep2::WriteError()
{
MessageBox("Fatal error:\nCannot write to serial port !","ROMDump Wizard - Error",MB_ICONSTOP|MB_OK);
EndDialog(IDCANCEL);
return 0;
}
int CStep2::ReadError()
{
MessageBox("Fatal error:\nCannot read from serial port !","ROMDump Wizard - Error",MB_ICONSTOP|MB_OK);
EndDialog(IDCANCEL);
return 0;
}
int CStep2::ProtocolError(int i)
{
char buffer[32];
wsprintf(buffer, "Protocol Error (%i)", i);
MessageBox(buffer,"ROMDump Wizard - Error",MB_ICONSTOP|MB_OK);
EndDialog(IDCANCEL);
return 0;
}
char *ROMDump[] =
{
"GROB 8 553 D9D20D8A812BF8111920BB000D9D2049703CCD20F14008F511108FC1523203481000C", // 1
"A13114B31A48409EA508508418F2D7608FD8F3520340FFFF0EF681AF048F2D7608FD8F3520340FFF", // 2
"F0EF681AF031F0110080820815901DD0808206159081AF13340FFF68B61481AF0181AF1CD5340FFF", // 3
"68BD40D5EC5606C7181AF0277E1808240000781AF0381AF13340FFF78B66060108706063416D9081", // 4
"AF0181AF1CD5340FFF78BD40D5EC5606A1181AF02870C17B21341F00F8FFB620791165F034000F78", // 5
"0434000E7804725134000FF80534000F780534000FF80534000E7805808240000881AF0381AF1334", // 6
"0FFFB8B63581AF0181AF1CD5340FFFB8BD40D5EC5606E6081AF027480345F00C8FAC620727080824", // 7
"0000C81AF0381AF1381AF0181AF1CD5340FFFF8BD40D5EC4A181AF0271308518F5F008732077711F", // 8
"0110080820015908F5E0108D3415081B58082415000C2134870D01F1F0076A001F5F008808240510", // 9
"0F4D8152715771547151716F17FCD57E01861531B000F714E1BA960814E8089714C1B8210014C340", //10
"000C80480481AF1113081AF1281AF00747031A37CD0156776507E9016F81AF10818F8F52D861B334", //11
"0000C8058058058051BA960814E8088714C1B8210014C1B040F714E01AF531F0AE76C20132D61328", //12
"0F480F080F480F380F180F3D53140AE7AE2A897D10BF5A6F5FE0131D07A2031A07220018082103A6", //13
"280821939EEC08082170A621F2110015B0808707F1D6114D010000000000000000B2130B2130", //14
NULL
};
DWORD WINAPI Step2_Thread(LPVOID lpdlg)
{
FILE *rom;
CStep2 *dlg = (CStep2*)lpdlg;
BYTE *res;
DWORD len;
int i, j;
//1-open serial port
if (SerialOpen()==FALSE) return dlg->OpenError();
STEPIT;
//2-ask for server mode
if (dlg->MessageBox("Please put your HP48 in SERVER mode.","ROMDump Wizard",MB_OKCANCEL)==IDCANCEL)
{
dlg->EndDialog(IDCANCEL);
return 0;
}
STEPIT;
//3-delete ROMDump if it already exists
res = (BYTE*)CommandPKT("CLEAR HEX 'ROMDump' PURGE",&len);
if (res==NULL) dlg->ProtocolError(1);
free(res);
STEPIT;
//4-send ROMDump to the HP48
do SendPKT('S',0,"~* @-#Y3"); while (RecvPKT()!='Y');
j = 0;
SendPKT('F',++j,"ROMDump");
if (RecvPKT()!='Y') dlg->ProtocolError(4);
STEPIT;
i=0;
while (ROMDump[i])
{
SendPKT('D',++j,ROMDump[i]);
if (RecvPKT()!='Y') dlg->ProtocolError(5+10*i);
i++;
STEPIT;
}
SendPKT('Z',++j,"");
if (RecvPKT()!='Y') dlg->ProtocolError(6);
SendPKT('B',++j,"");
if (RecvPKT()!='Y') dlg->ProtocolError(7);
//5-assemble ROMDump
res = (BYTE*)CommandPKT("ROMDump OBJ#Í ##4017h SYSEVAL ##56B6h SYSEVAL DROP NEWOB 'ROMDump' STO",&len);
if (res==NULL) dlg->ProtocolError(1);
free(res);
STEPIT;
//6-execute ROMDump to get HP48 type (G/S)
// dlg->MessageBox("Your HP48 will say 'Port Closed'. Just ignore it.","ROMDump Wizard", MB_OK);
res = (BYTE*)DumpRange(0x7FFF0,0x7FFFF);
if ((res[6]=='4')&&(res[7]=='8'))
Type = HP48S;
else
Type = HP48G;
free(res);
STEPIT;
//7-ok, now display the type and dump
dlg->m_State.SetWindowText("Now dumping the ROM...");
switch (Type)
{
case HP48S:
dlg->MessageBox("An HP48S/SX was detected.\n","ROMDump Wizard",MB_OK);
res = DumpRangeBin(dlg,0x00000,0x7FFFF);
if (RecvPKT()!='E') dlg->ProtocolError(9);
if (res==NULL)
{
dlg->MessageBox("Error while transfering the ROM.\n","ROMDump Wizard",MB_OK);
dlg->EndDialog(IDCANCEL);
return 0;
}
if (!CheckROM(res,HP48S))
{
dlg->MessageBox("ROM CRC check fails. Try again.\n","ROMDump Wizard",MB_OK);
dlg->EndDialog(IDCANCEL);
return 0;
}
rom = fopen("ROM.48S","wb");
for (i=0; i<=0x7FFFF; i++) fputc(res[i]&0xF, rom);
fclose(rom);
break;
case HP48G:
dlg->MessageBox("An HP48G/GX was detected.\n","ROMDump Wizard",MB_OK);
res = DumpRangeBin(dlg,0x00000,0xFFFFF);
if (res==NULL)
{
dlg->MessageBox("Error while transfering the ROM.\n","ROMDump Wizard",MB_OK);
dlg->EndDialog(IDCANCEL);
return 0;
}
if (!CheckROM(res,HP48G))
{
dlg->MessageBox("ROM CRC check fails. Try again.\n","ROMDump Wizard",MB_OK);
dlg->EndDialog(IDCANCEL);
return 0;
}
rom = fopen("ROM.48G","wb");
for (i=0; i<=0xFFFFF; i++) fputc(res[i]&0xF, rom);
fclose(rom);
break;
}
STEPIT;
//8-delete ROMDump
res = (BYTE*)CommandPKT("'ROMDump' PURGE",&len);
if (res==NULL) dlg->ProtocolError(1);
free(res);
STEPIT;
// All done !
dlg->EndDialog(IDOK);
return 0;
}
BOOL CStep2::OnInitDialog()
{
DWORD id_thread;
CDialog::OnInitDialog();
m_Progress.SetRange(0,STEPS);
m_Progress.SetStep(1);
m_Progress.SetPos(0);
h_thread = CreateThread(NULL,0,&Step2_Thread,(LPVOID)this,0,&id_thread);
return TRUE;
}
void CStep2::OnDestroy()
{
TerminateThread(h_thread,(DWORD)(-1));
SerialClose();
CDialog::OnDestroy();
}

View file

@ -1,43 +0,0 @@
// Step2.h : header file
//
#define _STEP2_
/////////////////////////////////////////////////////////////////////////////
// CStep2 dialog
class CStep2 : public CDialog
{
// Construction
public:
CStep2(CWnd* pParent = NULL); // standard constructor
int OpenError();
int WriteError();
int ReadError();
int ProtocolError(int i);
// Dialog Data
//{{AFX_DATA(CStep2)
enum { IDD = IDD_STEP2 };
CStatic m_State;
CButton m_Ok;
CProgressCtrl m_Progress;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CStep2)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HANDLE h_thread;
// Generated message map functions
//{{AFX_MSG(CStep2)
virtual BOOL OnInitDialog();
afx_msg void OnDestroy();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

View file

@ -1,52 +0,0 @@
// About.cpp : about box dialog
//
#include "stdafx.h"
#include "ROMDump.h"
#include "About.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*
{
}
{
CStep1 dlg;
dlg.Create(IDD_STEP1,m_pMainWnd);
dlg.ShowWindow(SW_SHOW);
if (nResponse != IDOK) return FALSE;
}
{
CStep2 dlg;
nResponse = dlg.Create(IDD_STEP2,m_pMainWnd);
if (nResponse != IDOK) return FALSE;
}
*/

View file

@ -1,31 +0,0 @@
//
// About.h : about box header file
//
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
// No message handlers
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

View file

@ -1,28 +0,0 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by ROMDump.rc
//
#define IDD_ABOUTBOX 100
#define IDR_MAINFRAME 128
#define IDR_ROMDUMTYPE 129
#define IDD_STEP1 130
#define IDD_STEP2 131
#define IDB_LCD1 132
#define IDC_PORT1 1001
#define IDC_PORT2 1002
#define IDC_PORT3 1003
#define IDC_PROGRESS 1003
#define IDC_PORT4 1004
#define IDC_STATE 1006
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 134
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

31
TRUELCD.KMI Normal file
View file

@ -0,0 +1,31 @@
Color 0 130 173 161
Color 1 128 166 159
Color 2 124 160 154
Color 3 119 155 148
Color 4 115 149 143
Color 5 110 143 137
Color 6 106 137 132
Color 8 102 132 126
Color 9 98 126 121
Color 10 93 120 115
Color 11 89 114 110
Color 12 83 109 104
Color 13 79 103 99
Color 14 74 97 93
Color 15 70 91 88
Color 16 65 86 82
Color 17 61 80 77
Color 18 57 74 71
Color 19 53 68 66
Color 20 48 63 60
Color 21 44 57 55
Color 22 39 51 49
Color 23 35 46 44
Color 24 31 41 38
Color 25 27 35 33
Color 26 22 29 27
Color 27 18 23 22
Color 28 13 18 16
Color 29 9 12 11
Color 30 4 6 5
Color 31 0 0 0

339
sources/COPYING.TXT Normal file
View file

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

237
sources/EMU48.TXT Normal file
View file

@ -0,0 +1,237 @@
Emu48 - A freeware HP48 Emulator for Windows 95 and NT
****************
* INSTALLATION *
****************
Emu48 is distributed in 3 separate archives :
- Emu48-1.x-bin.zip All the executables files (REQUIRED)
- Emu48-1.x-src.zip The sources of Emu48 and some useful tools (OPTIONAL)
- Emu48-com.zip Files common to all 1.x versions (REQUIRES)
To install Emu48, just unzip Emu48-1.x-bin.zip and Emu48-com.zip into an empty
directory. When you first run Emu48, it will detect the directory in which you
installed it, and will write its configuration to a file named Emu48.ini in
your Windows directory.
Note:
As of version 1.0, Emu48 will only run with Windows 95 and NT.
I am working on a port to Unix (XWindow). When this is finished,
I may port it to Windows 3.1 and OS/2.
Since the source code is provided, you can add features or port it to new
plateforms, but you are required to send me your changes.
************************
* YOU NEED A ROM IMAGE *
************************
Emu48 needs an image of the ROM of YOUR calculator to be able to run.
Since the ROM is copyrighted by HP, I won't give you mine, and you should not
give yours or make it freely available.
To use the ROM software of a calculator, you must be the owner of this
calculator.
- If you have already used another HP48 emulator, you can convert the ROM with
you were using with the Conver utility.
To do that, start a Command Promt while running Windows, and type :
Convert <old-file> ROM.48G
or Convert <old-file> ROM.48S
Where <old-file> is the path to your old ROM image. This will create a file
named ROM.48G or ROM.48S, depending on the version you own.
This tool should be able to read any style of ROM image, and will also check
its validity. Note than if you run it with only one parameter, no file will
be written, but it will still check the validity of the ROM.
- If you have never used an HP48 emulator, and don't have a ROM dump, you can
either use the old ROMDump utility and then Convert your dump, or you can
use my ROMDump Wizard, which will almost automatically get the ROM from your
HP48. However, this Wizard was written without a documentation on the
transfer protocol used by the HP48 (Kermit), so I cannot guarantee that it
will work. It worked on my computer, maybe it will work on yours. Try it !
WARNING: If you use ROMDump or the ROMDump Wizard, DO NOT INTERRUPT THE
PROCESS ! Your HP48 would lock, and the only way to reset it is
through the Reset hole.
IMPORTANT: To save a lot of space, two DLLs needed by the Romdump Wizard
have not been included in the Romdump Wizard's distribution.
They are called MSVCRT40.DLL and MFC40.DLL, and are available
on the Web at the Emu48 Official Homepage :
http://www.geocities.com/CapeCanaveral/5948/index.html
These two files are freely distributable, and would be included
in this archive if they weren't so large (about 1.4Mb for both)
Note that they are NOT needed by Emu48 : only the Romdump Wizard
requires them.
* Once you have your ROM dump(s), SAVE THEM TO A FLOPPY DISK !
It will save you a lot of troubles if you were to lose them.
****************
* HOW TO START *
****************
When Emu48 is installed and you have put the ROM image(s) in its directory, you
can start Emu48. You'll see a "Choose Your KML Script" box.
KML Scripts in fact define the visual aspect of Emu48, the behaviour of the
buttons, of the keyboard... It is a GREAT way to customize your copy of Emu48.
Check that the path in the "Emu48 Directory" text area is correct. Modify it if
the directory in which you installed Emu48 is not the directory displayed.
Click the refresh button ("V") after modifying it to update the list box.
Choose a KML script in the list box. If you have put a G/GX ROM dump in Emu48's
directory, choose a script for G/GX. If you have put a S/SX ROM dump in Emu48's
directory, choose a script for S/SX.
Several scripts are included in the common archive :
* Emu48's Default Faceplate for HP48G/GX
* Emu48's Default Faceplate for HP48S/SX
These two are simple scripts, and they use the bitmap from Win48 2.05.
* Casey's Gx with Toolbar and Touch Screen
* Casey's Sx with Toolbar and Touch Screen
These script uses many advanced features, and is a good demonstration of
the power of Emu48's scripting language, KML. Try it, it is really great !
* Floating buttons
This one looks really great.
* Small but realistic HP48 Gx
This one has been designed for small resolutions such as 640x480.
Note: some things in this script have to be be fixed.
If you want other great scripts, visit Casey's Emu48 homepage :
http://www.gulftel.com/~pattersc/emu48/
And if you are interested in writting new scripts, you'll want the KML 2.0
documentation, available on Casey's page and on my page :
http://www.geocities.com/CapeCanaveral/5948/kmlind.htm
Once you have selected a script, press Ok to start the emulator. While it is
running, you can use the View/Change Kml Script to change the visual aspect
of Emu48.
*******************
* SHARED RAM CARD *
*******************
You can add a SHARED (I'll explain later) ram card of up to 4Mb. By default, no such
card will be created when you start Emu48. The MkShared.exe utility, included in the
registered version, will allow you to create it.
The syntax is :
MkShared <filename> <size_in_kilobytes>
For example, you can create a 4Mb RAM card name SHARED.BIN (in Emu48's directory) with
the following command :
MkShared SHARED.BIN 4096
Valid sizes are 128, 256, 512, 1024, 2048 and 4096 kb.
When you have created this file, run Emu48, and use the Close menu item to close the
calculator state. Now select View/Settings. In the "Port 2" text area, type the name
of the file you created (if you don't include a path, it will be searched for in Emu48's
directory).
You can also tick the check box "Port 2 Is Shared".
When the box is cleared, only the first instance of Emu48 will allow you to use the RAM
card in Port 2.
When this box is ticked, the first instance of Emu48 will give you both read and write
access to this RAM card. If then you start Emu48 again, the RAM card in Port 2 will be
write-protected. You can thus transfer files very easily between two calculators. This
RAM card is used by both S/SX and G/GX types.
Note that you have to close Emu48 and restart it if you modify these settings.
********************
* SPECIAL FEATURES *
********************
Emu48 includes a backup feature (in the View menu). It save the complete state of the
calculator in the computer's memory. You might want to use it before doing something
risky, and if you don't want to save to the disk. It provides some kind of Undo feature.
It is also used by Emu48 when you want to save or load a new document, to restore its
old state if you cancel the operation or of something goes wrong.
********************
* TROUBLE SHOOTING *
********************
Q: The emulator display the keyboard, but the screen stays blank or is filled
with garbage.
A: Your ROM image is probably wrong. Check it with the Convert utility, and if
it says that the CRC is wrong, you should try to download your ROM again.
Q: What does this message mean :
"This file is missing or already loaded in another instance of Emu48."
A: Maybe you deleted or moved the files that the emulator tries to load when
starting (the last files you saved).
The other possibility is that you are running several instances of Emu48,
but you are trying to load the same file in both instances, which causes
a sharing violation.
***********
* SUPPORT *
***********
I cannot provide individual support for Emu48, but I will read all the mails
that you send.
All informations about Emu48 will be on the Emu48 Official Homepage on the Web :
http://www.geocities.com/CapeCanaveral/5948/index.html
Other graphics and scripts are available at Casey's Emu48 Graphics Page :
http://www.gulftel.com/~pattersc/emu48/
***************
* LEGAL STUFF *
***************
Emu48 - An HP48 Emulator
Copyright (C) 1997 Sebastien Carlier
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**************
* The Author *
**************
Paper Mail:
Sebastien Carlier
10 Allee des bergeronnettes
35340 LIFFRE
FRANCE
E-Mail:
sebc@epita.fr
sebc@anet.fr
Homepage:
http://www.geocities.com/CapeCanaveral/5948/index.html

672
sources/Emu48/CHANGES.TXT Normal file
View file

@ -0,0 +1,672 @@
Service Pack 10 for Emu48 Version 1.0
DISPLAY.C
- use only one pattern field for all display resolutions
- added new display contrast scheme
- bugfix in function WriteToMainDisplay(), calculated source memory
address was illegal memory pointer
EMU48.C
- bugfix in functions OnFileExit() and OnSysClose(), stop emulation
thread before saving emulation data
- changed function Disasm(), changed list box from single to multi
selectable items, added button to copy selected items to
clipboard
- moved function DragAcceptFiles() to WM_CREATE handler
- added function DragAcceptFiles() to WM_DESTROY handler
- allow second command line parameter as port2 filename
- added Critical Section initialisation
EMU48.H
- removed extern declaration of global function
- extern declaration of global variable and functions
EMU48.RC
- added button in dialog IDD_DISASM
- reinsert button IDC_UPDATE in dialog IDD_CHOOSEKML
- changed version and copyright
ENGINE.C
- functions CheckSerial() and AdjustSpeed() are inline coded now
- new function UpdateKdnBit() for updating the KDN bit by the 1ms
keyboard interrupt handler
FILES.C
- added new function CrcPort2() to get a fingerprint of port2
- changed function OpenDocument(), check fingerprint of port2
- changed function SaveDocument(), update fingerprint of port2
KEYBOARD.C
- changed function Keyboard_GetIR() to static
- bugfix in function ScanKeyboard(), added fixes for the KDN bit
implementation and update keyboard interrupt pending flag when
1ms keyboard handler is disabled
KML.C
- bugfix in function ParseLine(), caused memory leaks when an error
occured
- bugfix in function ParseLines(), fixed a windows program abort on
some KML script or line include errors
- bugfix in function ParseBlock(), abort parsing on KML script
errors
- bugfix in function ParseBlocks(), fixed a windows program abort on
block include errors
- bugfix in function FreeLines(), caused memory leaks when different
argument types are used in a line
MOPS.C
- added new function IOBit()
- bugfix in function ReadIO(), update the KDN bit in the SRQ2
register (0x119) before reading
OPCODES.H
- bugfix in A=IN and C=IN command, update KDN bit in the SRQ
register
- bugfix in all r=r+CON fs,n and r=r-CON fs,n opcodes, they always
work in HEX mode
- changes in INTON, INTOFF and RTI for KDN bit implementation
- changed RTI command, execute pending key interrupt only if enabled
- changed RSI command, set key interrupt pending flag also when 1ms
keyboard handler is disabled
- bugfix in INTON command, execute interrupt if key interrupt is
pending
OPS.H
- added new inline functions Ninc16() and Ndec16()
RESOURCE.H
- added/changed definitions
- removed ID_HELP_REGISTER
TYPES.H
- use position of the uUnused1 variable for fingerprint of port2
- use position of the Port2_Size variable for cpu cycles at start of
1ms key interrupt handler
Service Pack 9 for Emu48 Version 1.0
DISASM.C
- changed output of HP Mnemonic P=n
DISPLAY.C
- bugfix in function UpdateMainDisplay(), with off display and Zoom
> 1 only a part of the display was cleared
- changed function UpdateMenuDisplay(), use a common pointer offset
calculation and display output part now
EMU48.C
- changed function OnViewCopy(), changed screen clipboard format
from CF_BITMAP to CF_DIB
- bugfix in function OnViewReset(), must unconfig MMU on reset too
- changed function OnAbout(), don't stop emulation while viewing
About box
- moved initialize/remove of the Critical Section part from message
handler to main program
EMU48.H
- removed extern declaration of global variables and functions
EMU48.RC
- changed design of IDD_ABOUT
- changed version and copyright
ENGINE.C
- bugfix in function FASTPTR(), code execution is possible in IO
register area as well
FETCH.H
- removed jump to extension opcode 81B0
FILES.C
- removed global variable
MOPS.C
- bugfix in function MapP0(), MapP1(), MapP2(), MapBS(), mapping
area may have holes
- bugfix in function MapBS(), no read from ROM at mapped bank
switch control area
- bugfix in function MapP2(), if G(X) ROM select port2 only if
DA19=0 and BEN=1, now the saved bank switch control information is
used
- bugfix in function MapROM(), if G(X) ROM and DA19=0 (ROM disabled)
then mirror lower ROM at #80000 (AR18=0)
- bugfix in function Nread(), bank switching now works with every
'r=datx fsd' command in the complete mapped bank switch control
area, an unconfigured bank switch area is now disabled and the
GX bank switch information (content of FlipFlop) is saved now
- bugfix in function Nwrite(), at some conditions no update of the
display area and IO area couldn't be unconfigured
- removed functions Nread2(), Nwrite2(), Nread5() and Nwrite5()
- bugfix in function ReadIO(), several minor fixes in the LINECOUNT
register (0x128,0x129) emulation
- bugfix in function ReadIO(), the TIMER1CTRL and TIMER2CTRL
register (0x12E,0x12F) must be updated before reading
- bugfix in function WriteIO(), don't clear the XTRA bit in the
TIMER1CTRL register (0x12E) while setting
- bugfix in function WriteIO(), after setting new TIMER1CTRL and
TIMER2CTRL register (0x12E,0x12F) values the control bit
condition must be checked
- bugfix in function WriteIO(), handle start/stop of the LINECOUNT
register when the DON bit in the DISPIO (0x100) register has
changed
- bugfix in function WriteIO(), force new ROM mapping if DA19 in
the MSB LINECOUNT (0x129) register has changed on a G(X) ROM
OPCODES.H
- Nwrite2() replaced by Nwrite()
- Nwrite5() replaced by Nwrite()
- Nread2() replaced by Nread() for the BS 'r=datx fsd' bugfix
- Nread5() replaced by Nread() for the BS 'r=datx fsd' bugfix
- bugfix in RTI command, generate interrupt if ON key is pressed
- bugfix in RSI command, don't set key interrupt pending flag if
INTOFF command is active
- removed extension opcode 81B0
TIMER.C
- removed assertions in function CheckT1() and CheckT2() that the
timers must run
- moved initialize/remove of Critical Section handler from the
function StartTimers() and StopTimers() to main program for bugfix
the problems with the Critical Section area of the function
ReadT1() and ReadT2() when the timers are stopped
- bugfix in function ReadT2(), timer2 was always running
TYPES.H
- use Port2_Bank variable to save state of GX port2 Flip-Flop
Service Pack 8 for Emu48 Version 1.0
DISASM.C
- changed function read_nibble() to disassemble modules
- added new mapping functions for function read_nibble()
- bugfix in function append_imm_nibble(), HP Mnemonic hex number
was showed as decimal number
EMU48.C
- changed variable types of function WinMain()
- added "drag and drop" implementation for HP objects
- added some features to function Disasm()
- removed all parts handled with the global variables bAccurateTimer
and uT1Period
- bugfix in function Disasm(), button "Next Address" caused a
windows program abort if the given address was outside of the
cpu address area
- bugfix in function UpdateWindowStatus(), Menuitem Tools
"Disassembler..." must be disabled when document file is closed
- bugfix in function OnStackPaste(), fixed problem when HP is off
- bugfix in function OnObjectLoad(), solve problem when calculator
is off and bugfixed method to switch emulator into sleep state
- bugfix in function OnObjectSave(), bugfixed method to switch
emulator into sleep state
EMU48.DSP
- added library shell32.lib
EMU48.H
- bugfix of variable hApp, used wrong type
- extern declaration of global variables
- removed extern declaration of global variables
- added some disassembler defines
EMU48.RC
- added my name to dialog IDD_ABOUT
- added some radio buttons to dialog IDD_DISASM
- removed Timers part from dialog IDD_SETTINGS
- changed version and copyright
ENGINE.C
- added global variable
- removed global variable
- bugfix in function AdjKeySpeed(), slow down whole emulation now,
when a key is pressed
KEYBOARD.C
- changed key event signal in function KeyboardEvent()
MOPS.C
- bugfix in function Uncnfg(), I/O mapped address area begin and end
on a 64 nibble boundary, Chipset.IOBase must be saved for the C=ID
command
- bugfix in function C_Eq_Id(), don't shift Chipset.IOBase for ID
- changed function Nread(), Nwrite(), Nread2(), Nwrite2(), Nread5()
and Nwrite5(), test Chipset.IOCfig as well for mapping
OPCODES.H
- removed InfoMessage in BUSCB, BUSCC and BUSCD opcode, emulate as
NOP
- bugfix in RTI command, don't return from interrupt at timer1/2
interrupt condition
- bugfix in SHUTDN command, don't shut down at timer1/2 wake up
condition
- bugfix in RSI command, detection of interrupt is in service was
wrong
PCH.H
- added include shellapi.h
RESOURCE.H
- added several definitions
- removed IDC_BROWSEDIR, IDC_REFRESH, IDC_USEMMTIMER, IDC_T1PERIOD,
IDC_T1DEFAULT
TIMER.C
- removed global variables bAccurateTimer and uT1Period, replaced by
a static variable and a constant
- changed function CheckT1() and function CheckT2(), use function
parameter for the timer value now
- changed function ReadT1() and function ReadT2(), update timer
control bits after reading
- bugfix in function RescheduleT2(), execute timer2 event when MSB
of timer changed to update timer2 control register
- bugfix in function TimeProc(), waiting for timer2 overrun prevents
access to the timer2 value from the cpu emulation thread and reset
of variable uT2TimerId was outside synchronized area
- bugfix in function CheckT1() and function CheckT2(), fixed SRQ bit
handling
- bugfix in function SetT1() and function SetT2(), update timer
control bits and check for interrupts after setting
- bugfix in function StopTimers() and function SetT2(), killing
timer1 or timer2 in a Critical Section part may cause a dead lock
with the timer callback function (function timeKillEvent() waits
for the finish of the corresponding callback function, but the
callback function is locked by the Critical Section handler)
Service Pack 7 for Emu48 Version 1.0
DISASM.C
- new modul with disassembler
DISPLAY.C
- bugfixes in function UpdateDisplayPointers(), next line offset was
sometimes wrong and the addresses of the main display area were
wrong when next line offset was negative
- new implementation of function WriteToMainDisplay(), fixed several
bugs (no output when next line offset was negative, sometimes
problems with left margin values > 4 and garbage on display)
- bugfix in function WriteToMenuDisplay(), menu wasn't updated
when next line offset was negative
EMU48.C
- added global variable
- added semaphor handling for key scan
- added disassembler dialog box and menu entry
- bugfix in function OnViewCopy(), the clipboard wasn't closed when
EmptyClipboard() failed
- bugfix in function OnKeyDown(), suppress autorepeat feature of
keyboard
EMU48.DSP
- added disasm.c source
EMU48.H
- extern declaration of global variables
- added function prototypes
EMU48.RC
- added Menuitem Tools "Disassembler..."
- changed version and copyright
ENGINE.C
- added global variable
- bugfix in function AdjKeySpeed(), exit delay loop when a key
event has occured and use Chipset.Keyboard_Row[] instead of
Chipset.in to detect a pressed key
FILES.C
- function LoadBitmapFile() save old hWindowDC palette now
- bugfix in function SaveDocumentAs(), previous opened file wasn't
closed
KEYBOARD.C
- bugfix in function ScanKeyboard(), code part must be synchronized
and an interrupt was only generated when all input lines has been
low (no keys pressed)
- added parameter to function ScanKeyboard(), parameter indicates if
the Chipset.in interrupt register should be reset
- added key event signal in function KeyboardEvent()
- workaround in function KeyboardEvent(), hold key state for a
definite time
KML.C
- bugfix in function ParseLines() and ParseBlocks(), allocated
memory for string parameter of include token wasn't freed
- bugfix in function KillKML(), palette resource couldn't freed,
when hWindowDC was open
MOPS.C
- bugfix in function WriteIO(), the Chipset.start1 variable only
was updated when five nibbles at the DISPADDR register (0x120)
has been written
- bugfix in function WriteIO(), the Chipset.loffset variable only
was updated when three nibbles at the LINEOFFS register (0x125)
has been written
- bugfix in function WriteIO(), the Chipset.lcounter variable only
was updated when the MSB of the LINECOUNT register (0x129) has
been written
- bugfix in function WriteIO(), the Chipset.start2 variable only
was updated when five nibbles at the MENUADDR register (0x130)
has been written
- bugfix in function ReadIO(), the LINECOUNT register (0x128-0x129)
is a down counter
OPCODES.H
- changed RSI command for thread synchronize
RESOURCE.H
- added several definitions
TIMER.C
- bugfix in function SetAccesstime(), sync time values must always
save in port0 and not at the mapped address
- bugfix in function RescheduleT2(), used wrong event time when
reference point for timer2 value wasn't saved
Service Pack 6 for Emu48 Version 1.0
DDESERV.C
- bugfix in XTYP_POKE part, fixed problem when HP is off
DISPLAY.C
- added X4 display size parts
EMU48.C
- changed function OnViewCopy() for X4 display size
- init lFreq variable for high performance counter here now
EMU48.H
- changed type and name of bLcdDoubled to nLcdDoubled
- extern declaration of global variables
EMU48.RC
- changed version and copyright
EXTERNAL.C
- changed high limit of frequency, use SX specification
- added high limit of beep duration, use SX specification
- estimate cpu cycles for beep time
- adjust some cpu flags and registers modified by the original code
KML.C
- changed TOK_ZOOM implementation in function InitLcd()
MOPS.C
- changed implementation of registers 0x128-0x12D in function
ReadIO()
OPCODES.H
- update field select table in "EXTENSION opcode o81B1"
TIMER.C
- moved static lFreq variable to modul EMU48.C
Service Pack 5a for Emu48 Version 1.0
EMU48.C
- bugfix in OnPaint(), must redraw annunciators
Service Pack 5 for Emu48 Version 1.0
DDESERV.C
- return DDE error if emulator state couldn't change to sleep state
EMU48.C
- added Copy/Paste Clipboard data from/to stack (strings only)
EMU48.H
- extern declaration of global variables
- added function prototypes
EMU48.RC
- added Menuitem Edit "Copy String" and "Paste String"
- fixed multiple use of accelerator keys
- changed version and copyright
ENGINE.C
- added function WaitForSleepState(), wait for the SHUTDN command
-> stack isn't in use (when the clock is displayed, a time string
was sometimes on stack instead of the loaded item), then switch to
state 3 (Sleep state)
- added function AdjKeySpeed(), slow down key repetition
FILES.C
- save mapping size of port2 in global variable
- optimized calculation of bank switch mask in MapPort2()
MOPS.C
- bugfix in MapP0(), data offset was wrong
- bugfix in MapP1(), data offset was wrong
- bugfix in MapP2(), data offset was wrong and real size of modul
was zero
- bugfix in MapBS(), wrong pointer in mirrored data page
- bugfix in MapROM(), wrong pointer in mirrored data page
- bugfix in MapP0(), MapP1(), MapP2(), MapBS(), Config(), Uncnfg(),
mapped address area begin and end on a mapping size boundary
- bugfix in Map(), the access priority of CE1 and CE2 was wrong
(SX: port1<->port2, GX: port1<->bank select)
- bugfix in Uncnfg(), the unconfig priority of CE1 and CE2 was wrong
(SX: port1<->port2, GX: port1<->bank select)
- Map(), size optimized implementation
- Config(), size optimized implementation
- Uncnfg(), size optimized implementation
- C_Eq_Id(), size optimized implementation
OPCODES.H
- insert key slow down in A=IN and C=IN
RESOURCE.H
- added ID_STACK_COPY and ID_STACK_PASTE
Service Pack 4 for Emu48 Version 1.0
EMU48.C
- added code for port1 disable
- changed the default box setting of "Accurate Timer" in checked
EMU48.RC
- added item "Port 1 is Plugged"
- changed version and copyright
KEYBOARD.C
- bugfixes in 1 ms keyboard interrupt handler, keyboard interrupts
are generated at one of the following conditions: pressing the ON
key (non maskeable), pressing a key detected by the 1 ms keyboard
scan when enabled (maskeable), detect a key after an OUT command
or after the RSI command when a bit in the IN register is set
MOPS.C
- bugfix in WriteIO(), TIMER1 was loaded with the current value
OPCODES.H
- bugfix in INTON and INTOFF command, they aren't able to generate a
keyboard interrupt
- bugfix in RSI command, call interrupt routine or set interrupt
pending flag if a bit of the IN register is high
- RTI command changed, doesn't handle ON key here
- added InfoMessage for BUSCB command
RESOURCE.H
- added IDC_PORT1EN
SERIAL.C
- bugfix, synchronize threads for receive char
TIMER.C
- changed function CheckT1(), quite similar to V1.0 with minor fixes
- changed function CheckT2(), minor fixes
- bugfix in function SetT1(), decrement value after full period,
don't check for interrupts after setting
- bugfix in function SetT2(), don't check for interrupts after
setting
Service Pack 3 for Emu48 Version 1.0
DDESERV.C
- new modul for DDE communication
EMU48.C
- init DDE callback function and name service
- added section [Serial] in INI-File
- added combobox update in dialog box handler
EMU48.DSP
- new makefile for MSVC 5.0
EMU48.H
- extern declaration of global variables
- added function prototypes
EMU48.RC
- added block "Serial"
- changed version and copyright
ENGINE.C
- bugfix in SetSpeed(), may enable "realspeed" with illegal
reference counts
- bugfix in SwitchToState(), switching from "Invalid" or "Sleep"
state into another, ResumeThread() may called before
SuspendThread() (unsynchronized threads)
- added code for serial device
FILES.C
- separated stack writing code from LoadObject() to WriteStack()
MOPS.C
- added global variables
- changed code in ReadIO() for BAUD, IO CONTROL, RCS, TCS, RBR,
SREQ?, IR CONTROL for serial support
- changed code in WriteIO() for BAUD, IOC, TBR, IRC for serial
support
RESOURCE.H
- added IDC_WIRE and IDC_IR
SERIAL.C
- new modul for serial support
SERIAL.H
- new header with serial definitions
Service Pack 2 for Emu48 Version 1.0
DISPLAY.C
- bugfix in UpdateMainDisplay(), update display even if it's off
EMU48.C
- added section [Emulator] in INI-File
- added checkbox update in dialog box handler
EMU48.H
- extern declaration of variables
EMU48.RC
- added item "Authentic Calculator Speed"
- changed version and copyright
ENGINE.C
- added code to slow down emulation
RESOURCE.H
- added IDC_REALSPEED
Service Pack 1 for Emu48 Version 1.0
DISPLAY.C
- red and blue has been changed in SetLcdColor()
- use display contrast value from chipset and not the default
value in CreateLcdBitmap()
- use semaphores to avoid GDI trouble with NT in
UpdateMainDisplay(), UpdateMenuDisplay(), WriteToMainDisplay()
and WriteToMenuDisplay()
- execute ResizeWindow() only if window exist
- bugfix in draw part of WriteToMainDisplay()
EMU48.C
- version changed
- added global variable
- added semaphor handling to avoid GDI trouble with NT that prevent
graphic update sometimes
- added message for right mouse key
- bugfix of a parameter of GetPrivateProfileString()
- removed SwitchToState() and KillKML() at end of program
- eliminated memory leak caused by SetWindowTitle()
- function OnPaint() may returned without calling EndPaint()
- execute UpdateWindowStatus() only if window exist
EMU48.H
- extern declaration of global variable
- added VOID as parameter in function prototypes
EMU48.RC
- added/changed version and copyright
EXTERNAL.C
- bugfix, check if beeper enabled
- changed beeper emulation, more realistic with Windows NT
FILES.C
- avoid an open handle and adjust file attributes in
LoadBitmapFile()
- the WORD to int conversion used in function SetWindowPos()
failed; windows with negative position data wouldn't pop up with
NT (NT GDI is 32 bit coded, Windows 95 mostly 16 bit -> the
failed conversion doesn't matter with Windows 95)
- bugfix in close file handling of function OpenDocument()
- InitKML() need chipset for contrast setting in RestoreBackup()
KML.C
- added global variables
- use semaphores to avoid GDI trouble with NT in DrawButton() and
DrawAnnunciator()
- added function ReleaseAllButtons()
- changed mouse handling for pressing more than one key
OPCODES.H
- added S(X) oscillator cycles for each command
- bugfix in A=IN and C=IN command to emulate a saturn bug, on real
machines the assembler commands only work on an even address
- bugfix in all r=r+CON fs,n and r=r-CON fs,n opcodes to emulate a
saturn bug, on real machines commands with a single field selector
cause an overrun to other fields of the register
- NFdbl() replaced by NFadd()
- Ndbl() replaced by Nadd()
OPS.H
- NFinc() definition changed
- NFdec() definition changed
- NFdbl() definition removed
- Ndbl() function removed
- changed implementation of Ninc(), added offset variable
- changed implementation of Ndec(), added offset variable
- optimized implementation of Nadd()
- optimized implementation of Nsub()
- optimized implementation of Nrsub()
- optimized implementation of Nnot()
- optimized implementation of Nneg()
TIMER.C
- added global variables, defines and constants
- added function SetAccesstime() for setting the correct time
- bugfix in AbortT2() which prevent updating the clock sometime
- changed implementation of CheckT1() to correct blink frequency
of input cursor
- changed implementation of ReadT2() using a high resolution
timer to minimize skipping timer2 values
- bugfix in SetT2(), always check timer2 control register
- solved a problem with timer2 counts greater than 16.67 min.
- bugfix of wrong timer1/2 values (unsynchronized threads)
TYPES.H
- use position of the t2_ticks variable for oscillator cycles
(c) by Christoph Gießelink, cgiess@swol.de

137
sources/Emu48/DDESERV.C Normal file
View file

@ -0,0 +1,137 @@
/*
* DdeServ.c
*
* This file is part of Emu48
*
* Copyright (C) 1998 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
HSZ hsz1,HSZ hsz2,HDDEDATA hData,
DWORD dwData1,DWORD dwData2)
{
BYTE szBuffer[32];
HDDEDATA hReturn;
LPBYTE lpData;
DWORD dwAddress,dwSize,dwLoop,dwIndex;
BOOL bSuccess;
switch (iType)
{
case XTYP_CONNECT:
DdeQueryString(idDdeInst,hsz2,szBuffer,sizeof(szBuffer),0);
if (0 != strcmp(szBuffer,szAppName))
return (HDDEDATA) FALSE;
DdeQueryString(idDdeInst,hsz1,szBuffer,sizeof(szBuffer),0);
return (HDDEDATA) (0==strcmp(szBuffer,szTopic));
case XTYP_POKE:
// illegal data format or not in running state
if (iFmt != uCF_HpObj || nState != 0)
return (HDDEDATA) DDE_FNOTPROCESSED;
DdeAccessData(hData,&dwSize); // fetch data size
DdeUnaccessData(hData);
// reserve memory
if ((lpData = (LPBYTE) LocalAlloc(LMEM_FIXED,dwSize * 2)) == NULL)
return (HDDEDATA) DDE_FNOTPROCESSED;
if (!Chipset.dispon) // 25.08.98 cg, moved, HP off
{
// turn on HP
KeyboardEvent(TRUE,0,0x8000);
Sleep(200);
KeyboardEvent(FALSE,0,0x8000);
// while(Chipset.Shutdn == FALSE) Sleep(0); // 25.08.98 cg, removed
}
if (WaitForSleepState()) // 16.06.98 cg, wait for cpu SHUTDN then sleep state
{
LocalFree(lpData); // free memory
return (HDDEDATA) DDE_FNOTPROCESSED;
}
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==3);
// fetch data and write to stack
DdeGetData(hData,(LPBYTE) &dwIndex,sizeof(DWORD),0L);
if (dwIndex <= dwSize - sizeof(DWORD))
dwSize = dwIndex;
dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD));
bSuccess = (WriteStack(lpData,dwSize) == S_ERR_NO);
LocalFree(lpData); // free memory
SwitchToState(0); // run state
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==0);
if (bSuccess == FALSE)
return (HDDEDATA) DDE_FNOTPROCESSED;
KeyboardEvent(TRUE,0,0x8000);
Sleep(200);
KeyboardEvent(FALSE,0,0x8000);
// wait for sleep mode
while(Chipset.Shutdn == FALSE) Sleep(0);
return (HDDEDATA) DDE_FACK;
case XTYP_REQUEST:
// illegal data format or not in running state
if (iFmt != uCF_HpObj || nState != 0)
return NULL;
if (WaitForSleepState()) // 16.06.98 cg, wait for cpu SHUTDN then sleep state
return NULL;
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==3);
dwAddress = RPL_Pick(1); // pick address of level1 object
if (dwAddress == 0)
{
SwitchToState(0); // run state
return NULL;
}
dwLoop = dwSize = (RPL_SkipOb(dwAddress) - dwAddress + 1) / 2;
// length of binary header
dwIndex = sizeof(BINARYHEADER) - 1;
// size of objectsize + header + object
dwSize += dwIndex + sizeof(DWORD);
// reserve memory
if ((lpData = (LPBYTE) LocalAlloc(LMEM_FIXED,dwSize)) == NULL)
{
SwitchToState(0); // run state
return NULL;
}
// save data length
*(DWORD *)lpData = dwLoop + dwIndex;
// copy header
memcpy(lpData + sizeof(DWORD),BINARYHEADER,dwIndex);
// copy data
for (dwIndex += sizeof(DWORD);dwLoop--;++dwIndex,dwAddress += 2)
lpData[dwIndex] = Read2(dwAddress);
// write data
hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0);
LocalFree(lpData);
SwitchToState(0); // run state
while (nState!=nNextState) Sleep(0);
_ASSERT(nState==0);
return hReturn;
}
return NULL;
}

1899
sources/Emu48/DISASM.C Normal file

File diff suppressed because it is too large Load diff

753
sources/Emu48/DISPLAY.C Normal file
View file

@ -0,0 +1,753 @@
/*
* display.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
#include "kml.h"
#define LCD1_ROW 144
#define LCD2_ROW 288
#define LCD3_ROW 576 // 24.08.98 cg, new, X4 display
UINT nBackgroundX = 0;
UINT nBackgroundY = 0;
UINT nBackgroundW = 0;
UINT nBackgroundH = 0;
UINT nLcdX = 0;
UINT nLcdY = 0;
UINT nLcdDoubled = 1; // 24.08.98 cg, changed to integer var
LPBYTE pbyLcd;
HDC hLcdDC = NULL; // 22.01.98 cg, new, for security only
HDC hMainDC = NULL; // 22.01.98 cg, new, for security only
static HBITMAP hLcdBitmap;
static HBITMAP hMainBitmap;
static HBITMAP hOldLcdBitmap;
static HBITMAP hOldMainBitmap;
#define B 0x00FFFFFF
#define W 0x00000000
#define I 0xFFFFFFFF
static struct
{
BITMAPINFOHEADER Lcd_bmih;
DWORD dwColor[64];
} bmiLcd =
{
{0x28,0/*x*/,0/*y*/,1,8,BI_RGB,0,0,0,64,0},
{
W,B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,
B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I
}
};
#undef B
#undef W
#undef I
static DWORD Pattern[16]; // 29.01.99 cg, new, use only one pattern
// static DWORD Pattern4[16];
// static DWORD Pattern2[4];
// static DWORD Pattern1[2]; // 24.08.98 cg, new, pattern for X4
VOID UpdateContrast(BYTE byContrast) // 23.02.99 cg, changed, new implementation
{
DWORD c = byContrast;
DWORD b = byContrast + 0x20;
if (bmiLcd.dwColor[b] == 0xFFFFFFFF) b = 0;
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 1)
{
WORD i,j;
for (i=0; i<16; ++i)
{
Pattern[i] = 0;
for (j=8; j>0; j>>=1)
{
Pattern[i] = (Pattern[i] << 8) | ((i&j) ? c : b);
}
}
}
c = (c<<8) | c;
b = (b<<8) | b;
if (nLcdDoubled == 2)
{
Pattern[0] = (b<<16)|b;
Pattern[1] = (b<<16)|c;
Pattern[2] = (c<<16)|b;
Pattern[3] = (c<<16)|c;
}
c = (c<<16) | c;
b = (b<<16) | b;
if (nLcdDoubled == 4)
{
Pattern[0] = b;
Pattern[1] = c;
}
return;
}
VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue)
{
// 25.01.08 cg, bugfix, wrong bit position of red and blue
// 23.02.99 cg, changed, allow 64 colors now
bmiLcd.dwColor[nId&0x3F] = ((nRed&0xFF)<<16)|((nGreen&0xFF)<<8)|(nBlue&0xFF);
return;
}
VOID CreateLcdBitmap()
{
// create LCD bitmap
// 24.08.98 cg, changed implementation
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
bmiLcd.Lcd_bmih.biWidth = LCD1_ROW * nLcdDoubled;
bmiLcd.Lcd_bmih.biHeight = -64 * nLcdDoubled;
// 24.08.98 cg, end of changed implementation
hLcdDC = CreateCompatibleDC(hWindowDC);
hLcdBitmap = CreateDIBSection(hLcdDC, (BITMAPINFO*)&bmiLcd,DIB_RGB_COLORS, (LPVOID*)&pbyLcd, NULL, 0);
hOldLcdBitmap = SelectObject(hLcdDC, hLcdBitmap);
UpdateContrast(Chipset.contrast); // 23.01.98 cg, bugfix, use saved contrast
}
VOID DestroyLcdBitmap()
{
WORD i;
// 23.02.99 cg, new, clear background colors
for (i=32; i< 64; ++i) bmiLcd.dwColor[i] = 0xFFFFFFFF;
if (hLcdDC != NULL)
{
// destroy LCD bitmap
SelectObject(hLcdDC, hOldLcdBitmap);
DeleteObject(hLcdBitmap);
DeleteDC(hLcdDC);
hLcdDC = NULL;
hLcdBitmap = NULL;
hOldLcdBitmap = NULL;
}
return;
}
BOOL CreateMainBitmap(LPSTR szFilename)
{
hMainDC = CreateCompatibleDC(hWindowDC);
hMainBitmap = LoadBitmapFile(szFilename);
if (hMainBitmap == NULL)
{
DeleteDC(hMainDC);
return FALSE;
}
hOldMainBitmap = SelectObject(hMainDC, hMainBitmap);
SelectPalette(hMainDC, hPalette, FALSE);
return TRUE;
}
VOID DestroyMainBitmap()
{
if (hMainDC != NULL)
{
// destroy Main bitmap
SelectObject(hMainDC, hOldMainBitmap);
DeleteObject(hMainBitmap);
DeleteDC(hMainDC);
hMainDC = NULL;
hMainBitmap = NULL;
hOldMainBitmap = NULL;
}
return;
}
//****************
//*
//* LCD functions
//*
//****************
VOID UpdateDisplayPointers()
{
// 09.09.98 cg, bugfix, calculate display width
Chipset.width = (34 + Chipset.loffset + (Chipset.boffset / 4) * 2) & 0xFFFFFFFE;
Chipset.end1 = Chipset.start1 + (Chipset.lcounter + 1) * Chipset.width;
if (Chipset.end1 < Chipset.start1)
{
// 09.09.98 cg, bugfix, calculate first address of main display
Chipset.start12 = Chipset.end1 - Chipset.width;
// 09.09.98 cg, bugfix, calculate last address of main display
Chipset.end1 = Chipset.start1 - Chipset.width;
}
else
{
Chipset.start12 = Chipset.start1;
}
Chipset.end2 = Chipset.start2 + (63 - Chipset.lcounter) * 34;
}
static BYTE Buf[36];
static BOOL bScreenIsClean = FALSE;
VOID UpdateMainDisplay() // 29.04.98 cg, bugfix, update display even if it's off
{
UINT x, y;
INT nLines;
DWORD d = Chipset.start1;
BYTE *p = pbyLcd;
if (!Chipset.dispon)
{
nLines = 64;
if (!bScreenIsClean)
{
bScreenIsClean = TRUE;
// 24.08.98 cg, changed parameter
// 05.01.99 cg, bugfix, with Zoom > 1 only a part of the display was cleared
FillMemory(pbyLcd, LCD1_ROW * nLcdDoubled * nLines * nLcdDoubled, 0);
}
}
else
{
nLines = Chipset.lcounter + 1;
bScreenIsClean = FALSE;
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>1) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>2) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>3) & 1];
}
CopyMemory(p, p-LCD3_ROW, LCD3_ROW);
p+=LCD3_ROW;
CopyMemory(p, p-LCD3_ROW*2, LCD3_ROW*2);
p+=LCD3_ROW*2;
d+=Chipset.width;
}
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&3];
*(((DWORD*)p)++)=Pattern[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=Chipset.width;
}
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
d+=Chipset.width;
}
}
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
// 24.08.98 cg, use of new var type
BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdDoubled, nLines*nLcdDoubled, hLcdDC, Chipset.boffset*nLcdDoubled, 0, SRCCOPY);
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return;
}
VOID UpdateMenuDisplay()
{
UINT x, y;
BYTE *p;
DWORD d = Chipset.start2;
if (!Chipset.dispon) return;
if (Chipset.lcounter==0x3F) return; // menu disabled
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
// 18.01.99 cg, calculate offset once
p = pbyLcd + ((Chipset.lcounter+1)*nLcdDoubled*LCD1_ROW*nLcdDoubled);
if (nLcdDoubled == 4)
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>1) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>2) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>3) & 1];
}
CopyMemory(p, p-LCD3_ROW, LCD3_ROW);
p+=LCD3_ROW;
CopyMemory(p, p-LCD3_ROW*2, LCD3_ROW*2);
p+=LCD3_ROW*2;
d+=34;
}
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&3];
*(((DWORD*)p)++)=Pattern[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=34;
}
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
d+=34;
}
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
// 18.01.99 cg, use common output
BitBlt(hWindowDC, nLcdX, nLcdY+(Chipset.lcounter+1)*nLcdDoubled,
131*nLcdDoubled, (63-Chipset.lcounter)*nLcdDoubled,
hLcdDC, 0, (Chipset.lcounter+1)*nLcdDoubled, SRCCOPY);
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return;
}
VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
{
// 09.09.98 cg, new bugfixed implementation
// 09.03.99 cg, removed calculated corresponding source memory address
INT x0, x;
INT y0, y;
DWORD *p;
INT lWidth = abs(Chipset.width); // display width
d -= Chipset.start1; // nibble offset to DISPADDR (start of display)
d += 64 * lWidth; // make positive offset
y0 = abs((INT) d / lWidth - 64); // bitmap row
x0 = (INT) d % lWidth; // bitmap coloumn
y = y0; x = x0; // load loop variables
// outside main display area
_ASSERT(y0 >= 0 && y0 <= (INT) Chipset.lcounter);
// illegal zoom factor
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
// calculate memory position in LCD bitmap
p = (DWORD*) (pbyLcd + y0*LCD1_ROW*nLcdDoubled*nLcdDoubled
+ x0*sizeof(bmiLcd.dwColor[0])*nLcdDoubled);
while (s--) // loop for nibbles to write
{
if (x<36) // only fill visible area
{
if (nLcdDoubled == 4)
{
p[432] = p[288] = p[144] = p[0] = Pattern[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern[((*a)>>3) &1];
}
if (nLcdDoubled == 2)
{
p[72] = p[0] = Pattern[(*a)&3];
p[73] = p[1] = Pattern[(*a)>>2];
}
if (nLcdDoubled == 1)
{
*p = Pattern[*a];
}
}
++a; // next value to write
++x; // next x position
if ((x==lWidth)&&s) // end of display line
{
// end of main display area
if (y == (INT) Chipset.lcounter) break;
x = 0; // first coloumn
++y; // next row
// recalculate bitmap memory position of new line
p = (DWORD*) (pbyLcd+y*LCD1_ROW*nLcdDoubled*nLcdDoubled);
}
else
p += nLcdDoubled; // next x position in bitmap
}
// update window region
if (y0 != y) // changed more than one line
{
x0 = 0; // no x-position offset
x = 131; // redraw complete lines
++y; // redraw this line as well
}
else
{
x0 <<= 2; x <<= 2; // x-position in pixel
_ASSERT(x >= x0); // can't draw negative number of pixel
x -= x0; // number of pixels to update
x0 -= Chipset.boffset; // adjust x-position with left margin
if (x0 < 0) x0 = 0;
if (x0 > 131) x0 = 131; // cut right borders
if (x+x0 > 131) x = 131 - x0;
y = y0 + 1; // draw one line
}
x0 <<= nLcdDoubled / 2; // adjust dimensions to pixel size
x <<= nLcdDoubled / 2;
y0 <<= nLcdDoubled / 2;
y <<= nLcdDoubled / 2;
EnterCriticalSection(&csGDILock);
{
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x, y-y0, hLcdDC, x0+Chipset.boffset*nLcdDoubled, y0, SRCCOPY);
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
#if 0
// 09.09.98 cg, removed
UINT x0, x;
UINT y0, y;
DWORD *p;
if (Chipset.width<0) return;
d -= Chipset.start1;
y0 = y = d / Chipset.width;
x0 = x = d % Chipset.width;
// 05.03.98 cg, bugfix, cut right border later
// if ((x0*4+Chipset.boffset)>=131) return;
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
p = (DWORD*)(pbyLcd + y0*LCD3_ROW*4 + x0*16);
while (s--)
{
if (x<36)
{
p[432] = p[288] = p[144] = p[0] = Pattern1[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern1[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern1[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern1[((*a)>>3) &1];
}
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD3_ROW*4);
} else p+=4;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y+=3;
y0<<=2; y<<=2;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 524, y-y0, hLcdDC, Chipset.boffset*4, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=4; x<<=4;
if (x0>524) x0=524; // 05.03.98 cg, bugfix, cut right border
if (x >524) x =524;
y0<<=2; // y<<=1; // 09.03.98 cg, removed
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 4, hLcdDC, x0+Chipset.boffset*4, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<36)
{
p[72] = p[0] = Pattern2[(*a)&3];
p[73] = p[1] = Pattern2[(*a)>>2];
}
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y++;
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0, hLcdDC, Chipset.boffset*2, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=3; x<<=3;
if (x0>262) x0=262; // 05.03.98 cg, bugfix, cut right border
if (x >262) x =262;
y0<<=1; // y<<=1; // 09.03.98 cg, removed
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 2, hLcdDC, x0+Chipset.boffset*2, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<36) *p = Pattern4[*a];
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, Chipset.boffset, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=2; x<<=2;
if (x0>131) x0=131; // 05.03.98 cg, bugfix, cut right border
if (x >131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 1, hLcdDC, x0+Chipset.boffset, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
#endif
return;
}
VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
{
UINT x0, x;
UINT y0, y;
DWORD *p;
// if (Chipset.width<0) return; // 09.09.98 cg, bugfix, allow menu update
if (Chipset.lcounter==0x3F) return; // menu disabled
d -= Chipset.start2;
y0 = y = (d / 34) + (Chipset.lcounter+1);
x0 = x = d % 34;
if (x0 > 32) return; // 01.02.99 cg, changed, position out of viewed area
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
p = (DWORD*)(pbyLcd + y0*LCD3_ROW*4 + x0*16);
while (s--)
{
if (x<34)
{
p[432] = p[288] = p[144] = p[0] = Pattern[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern[((*a)>>3) &1];
}
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD3_ROW*4);
} else p+=4;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y0<<=2; y<<=2;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 524, y-y0+4, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=4; x<<=4;
y0<<=2; y<<=2;
if (x>524) x=524;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+4, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
// 24.08.98 cg, new, new part for X4
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<34)
{
p[72] = p[0] = Pattern[(*a)&3];
p[73] = p[1] = Pattern[(*a)>>2];
}
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0+2, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=3; x<<=3;
y0<<=1; y<<=1;
if (x>262) x=262;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+2, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<34) *p = Pattern[*a];
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=2; x<<=2;
if (x>131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+1, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
return;
}
VOID UpdateAnnunciators()
{
BYTE c;
c = (BYTE)(Chipset.IORam[0xB] | (Chipset.IORam[0xC]<<4));
if (!(c&0x80)) c=0;
DrawAnnunciator(1,c&0x01);
DrawAnnunciator(2,c&0x02);
DrawAnnunciator(3,c&0x04);
DrawAnnunciator(4,c&0x08);
DrawAnnunciator(5,c&0x10);
DrawAnnunciator(6,c&0x20);
return;
}
VOID ResizeWindow()
{
RECT rectWindow;
RECT rectClient;
if (hWnd == NULL) return; // 30.01.98 cg, bugfix, return if window closed
rectWindow.left = 0;
rectWindow.top = 0;
rectWindow.right = nBackgroundW;
rectWindow.bottom = nBackgroundH;
AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
GetClientRect(hWnd, &rectClient);
AdjustWindowRect(&rectClient, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
if (rectClient.bottom < rectWindow.bottom)
{
rectWindow.bottom += (rectWindow.bottom - rectClient.bottom);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
}
InvalidateRect(hWnd,NULL,TRUE);
return;
}

1611
sources/Emu48/EMU48.C Normal file

File diff suppressed because it is too large Load diff

194
sources/Emu48/EMU48.DSP Normal file
View file

@ -0,0 +1,194 @@
# Microsoft Developer Studio Project File - Name="Emu48" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=Emu48 - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Emu48.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Emu48.mak" CFG="Emu48 - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Emu48 - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "Emu48 - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "Emu48 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib /nologo /subsystem:windows /debug /machine:I386
!ENDIF
# Begin Target
# Name "Emu48 - Win32 Release"
# Name "Emu48 - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
# Begin Source File
SOURCE=.\ddeserv.c
# End Source File
# Begin Source File
SOURCE=.\disasm.c
# End Source File
# Begin Source File
SOURCE=.\display.c
# End Source File
# Begin Source File
SOURCE=.\Emu48.c
# End Source File
# Begin Source File
SOURCE=.\Emu48.rc
!IF "$(CFG)" == "Emu48 - Win32 Release"
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\engine.c
# End Source File
# Begin Source File
SOURCE=.\external.c
# End Source File
# Begin Source File
SOURCE=.\files.c
# End Source File
# Begin Source File
SOURCE=.\keyboard.c
# End Source File
# Begin Source File
SOURCE=.\kml.c
# End Source File
# Begin Source File
SOURCE=.\mops.c
# End Source File
# Begin Source File
SOURCE=.\pch.c
# ADD CPP /Yc"pch.h"
# End Source File
# Begin Source File
SOURCE=.\rpl.c
# End Source File
# Begin Source File
SOURCE=.\serial.c
# End Source File
# Begin Source File
SOURCE=.\timer.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=.\Emu48.h
# End Source File
# Begin Source File
SOURCE=.\kml.h
# End Source File
# Begin Source File
SOURCE=.\Ops.h
# End Source File
# Begin Source File
SOURCE=.\pch.h
# End Source File
# Begin Source File
SOURCE=.\types.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\Emu48.ico
# End Source File
# End Group
# End Target
# End Project

29
sources/Emu48/EMU48.DSW Normal file
View file

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 5.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "Emu48"=.\Emu48.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

219
sources/Emu48/EMU48.H Normal file
View file

@ -0,0 +1,219 @@
/*
* Emu48.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "types.h"
#define BINARYHEADER "HPHP48-W" // 11.05.98 cg, new
#define S_ERR_NO 0 // 11.05,98 cg, new, stack errorcodes
#define S_ERR_BINARY 1
#define S_ERR_ASCII 2
#define NO_SERIAL "disabled" // 22.05.98 cg, new, serial port not open
#define PORT_CLOSE 0 // 20.05.98 cg, new, COM port status
#define PORT_WIRE 1
#define PORT_IR 2
#define HP_MNEMONICS FALSE // 10.11.98 cg, new, disassembler mnenomics mode
#define CLASS_MNEMONICS TRUE
#define MEM_MAP 0 // 10.11.98 cg, new, memory module definition
#define MEM_ROM 1
#define MEM_RAM 2
#define MEM_PORT1 3
#define MEM_PORT2 4
// Emu48.c
extern HPALETTE hPalette;
extern HPALETTE hOldPalette; // 11.09.98 cg, old palette of hWindowDC
extern LPSTR szAppName; // 13.05.98 cg, application name for DDE server
extern LPSTR szTopic; // 13.05.98 cg, topic for DDE server
extern LPSTR szTitle;
extern CRITICAL_SECTION csGDILock; // 22.01.98 cg, critical section for hWindowDC
extern CRITICAL_SECTION csKeyLock; // 02.09.98 cg, critical section for key scan
extern CRITICAL_SECTION csIOLock; // 24.02.99 cg, critical section for I/O access
extern CRITICAL_SECTION csT1Lock; // 21.04.98 cg, critical section for timer1 access
extern CRITICAL_SECTION csT2Lock; // 21.04.98 cg, critical section for timer2 access
extern LARGE_INTEGER lFreq; // 24.08.98 cg, counter frequency
extern DWORD idDdeInst; // 13.05.98 cg, DDE server id
extern UINT uCF_HpObj; // 13.05.98 cg, DDE clipboard format
extern HINSTANCE hApp; // 01.11.98 cg, wrong variable type
extern HWND hWnd;
extern HDC hWindowDC;
extern BOOL bPort2IsShared;
extern BOOL bAlwaysDisplayLog;
extern UINT uTimer1Period;
extern VOID SetWindowTitle(LPSTR szString);
extern VOID UpdateWindowStatus(VOID);
// Display.c
extern UINT nBackgroundX;
extern UINT nBackgroundY;
extern UINT nBackgroundW;
extern UINT nBackgroundH;
extern UINT nLcdX;
extern UINT nLcdY;
extern UINT nLcdDoubled; // 24.08.98 cg, changed to integer var
extern LPBYTE pbyLcd;
extern HDC hLcdDC;
extern HDC hMainDC;
extern VOID UpdateContrast(BYTE byContrast);
extern VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue);
extern VOID CreateLcdBitmap(VOID);
extern VOID DestroyLcdBitmap(VOID);
extern BOOL CreateMainBitmap(LPSTR szFilename);
extern VOID DestroyMainBitmap(VOID);
extern VOID UpdateDisplayPointers(VOID);
extern VOID UpdateMainDisplay(VOID);
extern VOID UpdateMenuDisplay(VOID);
extern VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s);
extern VOID UpdateAnnunciators(VOID);
extern VOID ResizeWindow(VOID);
// Engine.c
extern BOOL bInterrupt;
extern UINT nState;
extern UINT nNextState;
extern BOOL bKeySlow; // 18.11.98 cg, slow down for key emulation
extern HANDLE hThread;
extern CHIPSET Chipset;
extern char szSerialWire[16]; // 20.05.98 cg, devicename for wire port
extern char szSerialIr[16]; // 20.05.98 cg, devicename for IR port
extern DWORD dwSXCycles; // 23.04.98 cg, SX cpu cycles in 1/16384 Hz
extern DWORD dwGXCycles; // 23.04.98 cg, GX cpu cycles in 1/16384 Hz
extern VOID SetSpeed(BOOL bAdjust); // 23.04.98 cg, set emulation speed
extern VOID UpdateKdnBit(VOID); // 25.02.99 cg, update KDN bit
extern BOOL WaitForSleepState(VOID); // 16.06.98 cg, wait for cpu SHUTDN then sleep state
extern UINT SwitchToState(UINT nNewState);
extern UINT WorkerThread(LPVOID pParam);
extern DWORD Npack(BYTE *a, UINT s);
extern VOID Nunpack(BYTE *a, DWORD b, UINT s);
// Files.c
extern char szEmu48Directory[260];
extern char szCurrentDirectory[260];
extern char szCurrentKml[260];
extern char szBackupKml[260];
extern char szCurrentFilename[260];
extern char szBackupFilename[260];
extern char szBufferFilename[260];
extern char szPort2Filename[260];
extern LPBYTE pbyRom;
extern DWORD dwRomSize;
extern char cCurrentRomType;
extern LPBYTE pbyPort2;
extern BOOL bPort2Writeable;
extern BOOL bPort2IsShared;
extern DWORD dwPort2Size; // 26.06.98 cg, size of mapped port2
extern DWORD dwPort2Mask;
// extern UINT nPort2Bank; // 15.12.98 cg, removed, not used any more
extern BOOL bBackup;
extern WORD WriteStack(LPBYTE,DWORD); // 11.05.98 cg, write object to stack
extern BOOL MapRom(LPCSTR szFilename);
extern VOID UnmapRom(VOID);
extern BOOL MapPort2(LPCSTR szFilename);
extern VOID UnmapPort2(VOID);
extern BOOL PatchRom(LPCSTR szFilename);
extern VOID ResetDocument(VOID);
extern BOOL NewDocument(VOID);
extern BOOL OpenDocument(LPCSTR szFilename);
extern BOOL SaveDocument(VOID);
extern BOOL SaveDocumentAs(LPCTSTR szFilename);
extern BOOL SaveBackup(VOID);
extern BOOL RestoreBackup(VOID);
extern BOOL ResetBackup(VOID);
extern BOOL GetOpenFilename(VOID);
extern BOOL GetSaveAsFilename(VOID);
extern BOOL GetLoadObjectFilename(VOID);
extern BOOL GetSaveObjectFilename(VOID);
extern BOOL LoadObject(LPCSTR szFilename);
extern BOOL SaveObject(LPCSTR szFilename);
extern HBITMAP LoadBitmapFile(LPCSTR szFilename);
// Timer.c
// extern BOOL bAccurateTimer; // 10.11.98 cg, removed, not adjustable any more
// extern UINT uT1Period; // 10.11.98 cg, removed, not adjustable any more
extern VOID StartTimers(VOID);
extern VOID StopTimers(VOID);
extern DWORD ReadT2(VOID);
extern VOID SetT2(DWORD dwValue);
extern BYTE ReadT1(VOID);
extern VOID SetT1(BYTE byValue);
// MOps.c
extern BOOL ioc_acc; // 17.05.98 cg, flag ioc changed
extern BOOL ir_ctrl_acc; // 17.05.98 cg, flag ir_ctl changed
extern LPBYTE RMap[256];
extern LPBYTE WMap[256];
extern VOID Map(BYTE a, BYTE b);
extern VOID Config(VOID);
extern VOID Uncnfg(VOID);
extern VOID Reset(VOID);
extern VOID C_Eq_Id(VOID);
extern VOID Npeek(BYTE *a, DWORD d, UINT s);
extern VOID Nread(BYTE *a, DWORD d, UINT s);
extern VOID Nwrite(BYTE *a, DWORD d, UINT s);
// extern VOID Nread2(BYTE *a, DWORD d); // 15.12.98 cg, removed, repaced by Nread()
// extern VOID Nwrite2(BYTE *a, DWORD d);// 15.12.98 cg, removed, repaced by Nwrite()
// extern VOID Nread5(BYTE *a, DWORD d); // 15.12.98 cg, removed, repaced by Nread()
// extern VOID Nwrite5(BYTE *a, DWORD d);// 15.12.98 cg, removed, repaced by Nwite()
extern BYTE Read2(DWORD d);
extern DWORD Read5(DWORD d);
extern VOID Write5(DWORD d, DWORD n);
extern VOID IOBit(DWORD d, BYTE b, BOOL s);// 24.02.99 cg, set/clear bit in I/O section
extern VOID ReadIO(BYTE *a, DWORD b, DWORD s);
extern VOID WriteIO(BYTE *a, DWORD b, DWORD s);
// Keyboard.c
// extern WORD Keyboard_GetIR(VOID); // 13.02.99 cg, is static now
extern VOID ScanKeyboard(BOOL bReset); // 02.09.98 cg, add flag for key state reset
extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in);
// RPL.c
extern DWORD RPL_SkipOb(DWORD d);
extern DWORD RPL_ObjectSize(BYTE *o);
extern DWORD RPL_CreateTemp(DWORD l);
extern DWORD RPL_Pick(UINT l);
extern VOID RPL_Replace(DWORD n);
extern VOID RPL_Push(DWORD n);
// External.c
extern VOID External(CHIPSET* w);
// DDEserv.c
extern HDDEDATA CALLBACK DdeCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD);
// Disasm.c
extern BOOL disassembler_mode;
extern WORD disassembler_map;
extern DWORD disassemble (DWORD addr, LPSTR out);
// Serial.c
extern WORD CommConnect(VOID);
extern VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort);
extern VOID CommClose(VOID);
extern VOID CommSetBaud(VOID);
extern VOID CommTransmit(VOID);
extern VOID CommReceive(VOID);
// Message Boxes
static __inline int InfoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND);}
static __inline int AbortMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);}
static __inline int YesNoMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNO|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
static __inline int YesNoCancelMessage(LPCSTR szMessage) {return MessageBox(hWnd, szMessage, szTitle, MB_APPLMODAL|MB_YESNOCANCEL|MB_ICONEXCLAMATION|MB_SETFOREGROUND);}
// Missing Win32 API calls
static __inline LPSTR DuplicateString(LPCSTR szString)
{
UINT uLength = strlen(szString) + 1;
LPSTR szDup = LocalAlloc(LMEM_FIXED,uLength); // 27.01.98 cg, adjust memsize
CopyMemory(szDup,szString,uLength);
return szDup;
}

View file

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View file

@ -28,13 +28,13 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,9,9,0 FILEVERSION 1,1,0,0
PRODUCTVERSION 0,9,9,0 PRODUCTVERSION 1,1,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x21L
#else #else
FILEFLAGS 0x0L FILEFLAGS 0x20L
#endif #endif
FILEOS 0x40004L FILEOS 0x40004L
FILETYPE 0x1L FILETYPE 0x1L
@ -45,13 +45,14 @@ BEGIN
BLOCK "00000000" BLOCK "00000000"
BEGIN BEGIN
VALUE "CompanyName", "Sebastien Carlier\0" VALUE "CompanyName", "Sebastien Carlier\0"
VALUE "FileDescription", "Emu48\0" VALUE "FileDescription", "HP48 Emulator\0"
VALUE "FileVersion", "0, 9, 9, 0\0" VALUE "FileVersion", "1, 1, 0, 0\0"
VALUE "InternalName", "Emu48\0" VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 1996\0" VALUE "LegalCopyright", "Copyright © 1999\0"
VALUE "OriginalFilename", "Emu48.exe\0" VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0" VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "0, 9, 9, 0\0" VALUE "ProductVersion", "1, 1, 0, 0\0"
VALUE "SpecialBuild", "Service Pack 10, Christoph Gießelink\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -87,7 +88,7 @@ BEGIN
MENUITEM "Save &As...", ID_FILE_SAVEAS, GRAYED MENUITEM "Save &As...", ID_FILE_SAVEAS, GRAYED
MENUITEM "&Close", ID_FILE_CLOSE, GRAYED MENUITEM "&Close", ID_FILE_CLOSE, GRAYED
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "&Settings...", ID_VIEW_SETTINGS MENUITEM "S&ettings...", ID_VIEW_SETTINGS
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "E&xit", ID_FILE_EXIT MENUITEM "E&xit", ID_FILE_EXIT
END END
@ -95,7 +96,11 @@ BEGIN
BEGIN BEGIN
MENUITEM "&Load Object...", ID_OBJECT_LOAD MENUITEM "&Load Object...", ID_OBJECT_LOAD
MENUITEM "&Save Object...", ID_OBJECT_SAVE MENUITEM "&Save Object...", ID_OBJECT_SAVE
MENUITEM "&Copy Screen", ID_VIEW_COPY, GRAYED MENUITEM SEPARATOR
MENUITEM "&Copy String", ID_STACK_COPY
MENUITEM "C&opy Screen", ID_VIEW_COPY
MENUITEM "&Paste String", ID_STACK_PASTE
MENUITEM SEPARATOR
MENUITEM "&Reset Calculator", ID_VIEW_RESET, GRAYED MENUITEM "&Reset Calculator", ID_VIEW_RESET, GRAYED
POPUP "&Backup" POPUP "&Backup"
BEGIN BEGIN
@ -109,6 +114,10 @@ BEGIN
BEGIN BEGIN
MENUITEM "Change &KML Script...", ID_VIEW_SCRIPT MENUITEM "Change &KML Script...", ID_VIEW_SCRIPT
END END
POPUP "&Tools"
BEGIN
MENUITEM "&Disassembler...", ID_TOOL_DISASM
END
POPUP "&Help" POPUP "&Help"
BEGIN BEGIN
MENUITEM "&About Emu48...", ID_ABOUT MENUITEM "&About Emu48...", ID_ABOUT
@ -147,49 +156,54 @@ END
// Dialog // Dialog
// //
IDD_ABOUT DIALOGEX 0, 0, 261, 194 IDD_ABOUT DIALOGEX 0, 0, 261, 160
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About Emu48" CAPTION "About Emu48"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,21,20,SS_REALSIZEIMAGE, ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE,
WS_EX_TRANSPARENT WS_EX_TRANSPARENT
LTEXT "",IDC_VERSION,32,6,151,8,NOT WS_GROUP LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 1997 Sébastien Carlier",IDC_STATIC,32,18, LTEXT "Copyright © 1999 Sébastien Carlier && Christoph Gießelink",
151,8 IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14 DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY,WS_EX_DLGMODALFRAME ES_READONLY
END END
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 162, 180 IDD_SETTINGS DIALOGEX 0, 0, 167, 178
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings" CAPTION "Settings"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN BEGIN
GROUPBOX "General",IDC_STATIC,7,4,153,63
GROUPBOX "Memory Cards",IDC_STATIC,7,70,153,50
GROUPBOX "Serial Ports",IDC_STATIC,7,124,153,27
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,104,10
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,16,92,10 BS_AUTOCHECKBOX | WS_TABSTOP,13,26,89,10
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,29,117,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,39,114,10
CONTROL "Always display KML Compilation Result", CONTROL "Always display KML Compilation Result",
IDC_ALWAYSDISPLOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, IDC_ALWAYSDISPLOG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
14,42,138,10 13,52,136,10
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,79,67,10
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,70,73,10 BS_AUTOCHECKBOX | WS_TABSTOP,84,79,69,10
CONTROL "Port 2 Is Shared",IDC_PORT2ISSHARED,"Button", CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,83,65,10 BS_AUTOCHECKBOX | WS_TABSTOP,13,92,65,10
LTEXT "Port 2 File :",IDC_STATIC,13,96,37,8 LTEXT "Port 2 File :",IDC_STATIC,13,105,37,8
EDITTEXT IDC_PORT2,51,94,99,12,ES_AUTOHSCROLL EDITTEXT IDC_PORT2,51,103,104,12,ES_AUTOHSCROLL
LTEXT "Timer 1 Period :",IDC_STATIC,13,136,60,9 LTEXT "Wire:",IDC_STATIC,13,136,17,8
EDITTEXT IDC_T1PERIOD,73,134,35,12,ES_AUTOHSCROLL COMBOBOX IDC_WIRE,31,134,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
PUSHBUTTON "&Default",IDC_T1DEFAULT,109,134,41,12 WS_TABSTOP,WS_EX_LEFTSCROLLBAR
DEFPUSHBUTTON "&Ok",IDOK,7,159,50,14 LTEXT "IR:",IDC_STATIC,89,136,9,8
PUSHBUTTON "&Cancel",IDCANCEL,105,159,50,14 COMBOBOX IDC_IR,107,134,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
GROUPBOX "General",IDC_STATIC,7,7,148,50 WS_TABSTOP
GROUPBOX "Memory Cards",IDC_STATIC,7,61,148,50 DEFPUSHBUTTON "&Ok",IDOK,9,157,50,14
GROUPBOX "Timers",IDC_STATIC,7,113,148,40 PUSHBUTTON "&Cancel",IDCANCEL,107,157,50,14
CONTROL "Accurate Timer (may be slower)",IDC_USEMMTIMER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,123,136,10
END END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 186, 66 IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 186, 66
@ -225,6 +239,37 @@ BEGIN
WS_BORDER | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_CLIENTEDGE WS_BORDER | WS_VSCROLL | NOT WS_TABSTOP,WS_EX_CLIENTEDGE
END END
IDD_DISASM DIALOGEX 0, 0, 255, 165
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Disassembler"
FONT 8, "Courier New", 0, 0, 0x1
BEGIN
LTEXT "Address (HEX):",IDC_ADDRESS,7,147,46,8
EDITTEXT IDC_DISASM_ADR,56,145,36,12,ES_AUTOHSCROLL
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14
PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14
GROUPBOX "Module",IDC_DISASM_MODULE,7,5,166,26
CONTROL "Map",IDC_DISASM_MAP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,14,16,28,10
CONTROL "ROM",IDC_DISASM_ROM,"Button",BS_AUTORADIOBUTTON,45,16,
28,10
CONTROL "RAM",IDC_DISASM_RAM,"Button",BS_AUTORADIOBUTTON,76,16,
28,10
CONTROL "Port 1",IDC_DISASM_PORT1,"Button",BS_AUTORADIOBUTTON,
107,16,28,10
CONTROL "Port 2",IDC_DISASM_PORT2,"Button",BS_AUTORADIOBUTTON,
138,16,28,10
GROUPBOX "Mnemonics",IDC_DISASM_MNEMONICS,180,5,68,26
CONTROL "HP",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,187,16,24,10
CONTROL "Class",IDC_DISASM_CLASS,"Button",BS_AUTORADIOBUTTON,215,
16,31,10
LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP,WS_EX_NOPARENTNOTIFY
END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
@ -234,22 +279,6 @@ END
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE GUIDELINES DESIGNINFO DISCARDABLE
BEGIN BEGIN
IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 254
TOPMARGIN, 6
BOTTOMMARGIN, 187
END
IDD_SETTINGS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 155
TOPMARGIN, 7
BOTTOMMARGIN, 173
END
IDD_CHOOSEKML, DIALOG IDD_CHOOSEKML, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
@ -265,6 +294,14 @@ BEGIN
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 160 BOTTOMMARGIN, 160
END END
IDD_DISASM, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 248
TOPMARGIN, 5
BOTTOMMARGIN, 158
END
END END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED

379
sources/Emu48/ENGINE.C Normal file
View file

@ -0,0 +1,379 @@
/*
* engine.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
#include "Serial.h"
// HST bits
#define XM 1
#define SB 2
#define SR 4
#define MP 8
#pragma intrinsic(memset,memcpy)
#define w Chipset
#define PCHANGED ((void)(F_s[0]=w.P,F_l[1]=w.P+1))
#define GOYES3 {if(w.carry)goto o_goyes3;else{w.pc+=2;continue;}}
#define GOYES5 {if(w.carry)goto o_goyes5;else{w.pc+=2;continue;}}
#define INTERRUPT ((void)(w.SoftInt=TRUE,bInterrupt=TRUE))
#define SAMPLE 16384 // 23.04.98 cg, new, speed adjust sample frequency
// 23.04.98 cg, new, cpu cycles for interval
#define T2CYCLES ((cCurrentRomType=='S')?dwSXCycles:dwGXCycles)
//#define FASTPTR(d) (RMap[d>>12]+(d&0xFFF))
static __inline LPBYTE FASTPTR(DWORD d)
{
// 17.12.98 cg, bugfix, code is running in IO area as well
if ((Chipset.IOCfig)&&((d&0xFFFC0)==Chipset.IOBase))
return Chipset.IORam+d-Chipset.IOBase;
return RMap[d>>12]+(d&0xFFF);
}
#include "Ops.h"
BOOL bInterrupt = FALSE;
UINT nState = 1;
UINT nNextState = 0;
BOOL bKeySlow = FALSE; // 18.11.98 cg, new, slow down for key emulation
CHIPSET Chipset;
char szSerialWire[16]; // 20.05.98 cg, new, devicename for wire port
char szSerialIr[16]; // 20.05.98 cg, new, devicename for IR port
DWORD dwSXCycles = 82; // 23.04.98 cg, new, SX cpu cycles in interval
DWORD dwGXCycles = 123; // 23.04.98 cg, new, GX cpu cycles in interval
static BOOL bCommInit = FALSE; // 17.05.98 cg, new, COM port not open
static BOOL bRealSpeed = FALSE; // 23.04.98 cg, new, enable/disable real speed
static DWORD dwOldCyc; // 23.04.98 cg, new, cpu cycles at last event
static DWORD dwSpeedRef; // 23.04.98 cg, new, timer value at last event
static DWORD dwTickRef; // 23.04.98 cg, new, sample timer ticks
static __inline VOID CheckSerial(VOID) // 17.05.98 cg, new function
// 25.02.99 cg, changed, inline coded now
{
if (ioc_acc) // IOC changed
{
ioc_acc = FALSE;
// COM port closed and serial on
if (bCommInit == FALSE && (Chipset.IORam[IO_CTRL] & SON) != 0)
{
CommOpen(szSerialWire,szSerialIr); // open COM ports
bCommInit = CommConnect() != PORT_CLOSE;
}
// COM port opend and serial off
if (bCommInit == TRUE && (Chipset.IORam[IO_CTRL] & SON) == 0)
{
CommClose(); // close COM port
bCommInit = FALSE;
}
// Interrupt on recv buffer full and receive buffer full
if ((Chipset.IORam[IO_CTRL] & ERBF) && (Chipset.IORam[RCS] & RBF))
{
Chipset.Shutdn = FALSE;
INTERRUPT;
}
}
}
static __inline VOID AdjustSpeed(VOID) // 23.04.98 cg, new, adjust emulation speed
// 25.02.99 cg, changed, inline coded now
{
if (bRealSpeed || bKeySlow) // 18.11.98 cg, changed, slow down
{
// cycles elapsed for next check
if (Chipset.cycles-dwOldCyc >= (DWORD) T2CYCLES)
{
LARGE_INTEGER lAct;
do
{
BOOL bErr = QueryPerformanceCounter(&lAct);
_ASSERT(bErr); // no high-resolution performance counter
}
while(lAct.LowPart-dwSpeedRef <= dwTickRef);
dwOldCyc += T2CYCLES; // adjust cycles reference
dwSpeedRef += dwTickRef; // adjust reference time
}
}
return;
}
static VOID AdjKeySpeed(VOID) // 05.07.98 cg, new, slow down key repeat
// 18.11.98 cg, bugfix, slow down whole emulation,
// when key pressed
{
WORD i;
BOOL bKey;
if (bRealSpeed) return; // no need to slow down
bKey = FALSE; // search for a pressed key
for (i = 0;i < sizeof(Chipset.Keyboard_Row) / sizeof(Chipset.Keyboard_Row[0]) && !bKey;++i)
bKey = (Chipset.Keyboard_Row[i] != 0);
if (!bKeySlow && bKey) // key pressed, init variables
{
LARGE_INTEGER lTime; // sample timer ticks
dwOldCyc = Chipset.cycles; // save reference cycles
QueryPerformanceCounter(&lTime); // get timer ticks
dwSpeedRef = lTime.LowPart; // save reference time
}
bKeySlow = bKey; // save new state
return;
}
VOID SetSpeed(BOOL bAdjust) // 23.04.98 cg, new, set emulation speed
{
if (bAdjust) // 15.05.98 cg, changed, switch to real speed
{
LARGE_INTEGER lTime; // sample timer ticks
dwOldCyc = Chipset.cycles; // save reference cycles
QueryPerformanceCounter(&lTime); // get timer ticks
dwSpeedRef = lTime.LowPart; // save reference time
}
bRealSpeed = bAdjust; // 15.05.98 cg, bugfix, save emulation speed
}
VOID UpdateKdnBit(VOID) // 25.02.99 cg, new, update KDN bit
{
if (Chipset.intk && Chipset.cycles - Chipset.dwKdnCycles > (DWORD) T2CYCLES * 16)
IOBit(0x19,8,Chipset.in != 0);
}
BOOL WaitForSleepState(VOID) // 16.06.98 cg, new, wait for cpu SHUTDN then sleep state
{
DWORD dwRefTime = timeGetTime();
// wait for the SHUTDN command with 1.5 sec timeout
while (timeGetTime() - dwRefTime < 1500L && !Chipset.Shutdn)
Sleep(0);
if (Chipset.Shutdn) // not timeout, cpu is down
SwitchToState(3); // go to sleep state
return 3 != nNextState; // state not changed, emulator was busy
}
UINT SwitchToState(UINT nNewState)
{
UINT nOldState = nState;
if (nState == nNewState) return nOldState;
switch (nState)
{
case 0: // Run
switch (nNewState)
{
case 1: // -> Invalid
nNextState = 1;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
nNextState = 2;
ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 3: // -> Sleep
nNextState = 3;
if (Chipset.Shutdn)
ResumeThread(hThread);
else
bInterrupt = TRUE;
while (nState!=nNextState) Sleep(0);
break;
}
break;
case 1: // Invalid
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
bInterrupt = FALSE;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 2;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
break;
case 3: // -> Sleep
nNextState = 3;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
}
break;
case 3: // Sleep
switch (nNewState)
{
case 0: // -> Run
nNextState = 0;
if (Chipset.Shutdn) bInterrupt=TRUE;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
//while (nState!=nNextState) Sleep(0);
break;
case 1: // -> Invalid
nNextState = 1;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
case 2: // -> Return
nNextState = 1;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
nNextState = 2;
// 16.05.98 cg, bugfix, wait until thread is down, then resume
while (ResumeThread(hThread)==0) Sleep(0);
// ResumeThread(hThread);
while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break;
}
break;
}
return nOldState;
}
UINT WorkerThread(LPVOID pParam)
{
LARGE_INTEGER lDummyInt; // 23.04.98 cg, new, sample timer ticks
QueryPerformanceFrequency(&lDummyInt); // 23.04.98 cg, new, init timer ticks
lDummyInt.QuadPart /= SAMPLE; // 23.04.98 cg, new, calculate sample ticks
dwTickRef = lDummyInt.LowPart; // 23.04.98 cg, new, sample timer ticks
_ASSERT(dwTickRef); // 23.04.98 cg, new, tick resolution error
loop:
while (nNextState == 1) // go into invalid state
{
CommClose(); // 17.05.98 cg, new, close COM port
bCommInit = FALSE; // 17.05.98 cg, new, COM port not open
nState = 1; // in invalid state
SuspendThread(hThread); // sleep thread
if (nNextState == 2) // go into return state
{
nState = 2; // in return state
return 0; // kill thread
}
ioc_acc = TRUE; // 17.05.98 cg, new, test if UART on
}
while (nNextState == 0)
{
if (nState!=0)
{
nState = 0;
if (Chipset.type == 'S')
{
Chipset.cards_status &= 0x5;
if (pbyPort2) Chipset.cards_status |= 0x2;
if (bPort2Writeable) Chipset.cards_status |= 0x8;
}
else
{
Chipset.cards_status &= 0xA;
if (pbyPort2) Chipset.cards_status |= 0x1;
if (bPort2Writeable) Chipset.cards_status |= 0x4;
}
UpdateDisplayPointers();
UpdateMainDisplay();
UpdateMenuDisplay();
UpdateAnnunciators();
// 23.04.98 cg, new, init speed reference
dwOldCyc = Chipset.cycles;
QueryPerformanceCounter(&lDummyInt);
dwSpeedRef = lDummyInt.LowPart;
// 23.04.98 cg, end of init
StartTimers();
}
PCHANGED;
while (!bInterrupt)
{
do
{
LPBYTE I = FASTPTR(w.pc);
#include "Fetch.h"
#include "Opcodes.h"
}
while(0); // 23.04.98 cg, workaround for continue
CheckSerial(); // 17.05.98 cg, serial support
AdjustSpeed(); // 23.04.98 cg, adjust emulation speed
}
if (Chipset.Shutdn)
{
bInterrupt = FALSE;
SuspendThread(hThread);
Chipset.Shutdn = FALSE;
// 23.04.98 cg, new, init speed reference
dwOldCyc = Chipset.cycles;
QueryPerformanceCounter(&lDummyInt);
dwSpeedRef = lDummyInt.LowPart;
// 23.04.98 cg, end of init
}
if (Chipset.SoftInt)
{
bInterrupt = FALSE;
Chipset.SoftInt = FALSE;
if (Chipset.inte)
{
Chipset.inte = FALSE;
rstkpush(Chipset.pc);
Chipset.pc = 0xf;
}
}
if (nNextState != 0)
{
StopTimers();
Chipset.cards_status &= (Chipset.type=='S')?0x5:0xA;
}
}
while (nNextState == 3) // go into sleep state
{
nState = 3; // in sleep state
SuspendThread(hThread); // sleep thread
}
goto loop;
UNREFERENCED_PARAMETER(pParam);
}

64
sources/Emu48/EXTERNAL.C Normal file
View file

@ -0,0 +1,64 @@
/*
* external.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
// 02.02.98 cg, new, memory address for flags -53 to -56
#define SFLAG53_56 ((cCurrentRomType=='S')?0x706D2:0x80850)
static __inline VOID Return(CHIPSET* w)
{
w->rstkp=(w->rstkp-1)&7;
w->pc = w->rstk[w->rstkp];
w->rstk[w->rstkp] = 0;
return;
}
VOID External(CHIPSET* w)
{
if (w->pc==0x017A6) // Beep
{
// begin with patch
// 02.02.98 cg, changed for better emulation
BYTE fbeep;
DWORD freq,dur;
freq = Npack(w->D,5); // frequency in Hz
dur = Npack(w->C,5); // duration in ms
Nread(&fbeep,SFLAG53_56,1); // fetch system flags -53 to -56
w->carry = TRUE; // 22.07.98 cg, setting of no beep
if (!(fbeep & 0x8) && freq) // bit -56 clear and frequency > 0 Hz
{
if (freq < 37) freq = 37; // low limit of freqency (NT)
if (freq > 4400) freq = 4400; // 22.07.98 cg, high limit of HP (SX)
if (dur > 1048575) // 22.07.98 cg, high limit of HP (SX)
dur = 1048575;
Beep(freq,dur); // NT: ok, Windows 95: default sound or standard system beep
// 22.07.98 cg, estimate cpu cycles for beeping time (2MHz / 4MHz)
w->cycles += dur * ((cCurrentRomType=='S') ? 2000 : 4000);
// original routine return with...
w->P = 0; // 22.07.98 cg, P=0
w->intk = TRUE; // 22.07.98 cg, INTON
w->carry = FALSE; // 22.07.98 cg, RTNCC
}
// MessageBeep(0xFFFFFFFF); // original, replaced
// continue with original part
//Beep(600,50);
Return(w);
return;
}
w->pc +=4;
return;
}

View file

@ -380,7 +380,7 @@ o81B_:
switch(I[3]) switch(I[3])
{ {
//////// EXTENSIONS //////// //////// EXTENSIONS ////////
case 0x0: goto o81B0; // case 0x0: goto o81B0; // 05.01.99 cg, removed, unused extension
case 0x1: goto o81B1; case 0x1: goto o81B1;
//////////////////////////// ////////////////////////////
case 0x2: goto o81B2; case 0x2: goto o81B2;

View file

@ -30,8 +30,9 @@ static HANDLE hPort2Map = NULL;
LPBYTE pbyPort2 = NULL; LPBYTE pbyPort2 = NULL;
BOOL bPort2Writeable = FALSE; BOOL bPort2Writeable = FALSE;
BOOL bPort2IsShared = FALSE; BOOL bPort2IsShared = FALSE;
DWORD dwPort2Size = 0; // 26.06.98 cg, new, size of mapped port2
DWORD dwPort2Mask = 0; DWORD dwPort2Mask = 0;
UINT nPort2Bank = 0; // UINT nPort2Bank = 0; // 15.12.98 cg, removed, not used any more
static BYTE pbySignatureE[16] = "Emu48 Document\xFE"; static BYTE pbySignatureE[16] = "Emu48 Document\xFE";
static BYTE pbySignatureW[16] = "Win48 Document\xFE"; static BYTE pbySignatureW[16] = "Win48 Document\xFE";
@ -40,6 +41,59 @@ static HANDLE hCurrentFile = NULL;
static CHIPSET BackupChipset; static CHIPSET BackupChipset;
BOOL bBackup = FALSE; BOOL bBackup = FALSE;
//################
//#
//# Subroutine for Write on Stack
//#
//################
WORD WriteStack(LPBYTE lpBuf,DWORD dwSize) // 11.05.98 cg, new, separated from LoadObject()
{
BOOL bBinary;
DWORD dwLength, dwAddress, i;
bBinary = ((lpBuf[dwSize+0]=='H')
&& (lpBuf[dwSize+1]=='P')
&& (lpBuf[dwSize+2]=='H')
&& (lpBuf[dwSize+3]=='P')
&& (lpBuf[dwSize+4]=='4')
&& (lpBuf[dwSize+5]=='8')
&& (lpBuf[dwSize+6]=='-'));
for (i=0; i<dwSize; i++)
{
BYTE byTwoNibs = lpBuf[i+dwSize];
lpBuf[i*2 ] = (BYTE)(byTwoNibs&0xF);
lpBuf[i*2+1] = (BYTE)(byTwoNibs>>4);
}
if (bBinary == TRUE)
{ // load as binary
dwLength = RPL_ObjectSize(lpBuf+16);
dwAddress = RPL_CreateTemp(dwLength);
if (dwAddress == 0) return S_ERR_BINARY;
// 23.05.98 cg, optimized
Nwrite(lpBuf+16, dwAddress, dwLength);
}
else
{ // load as string
BYTE lpHead[5];
dwLength = dwSize*2;
dwAddress = RPL_CreateTemp(dwLength+10);
if (dwAddress == 0) return S_ERR_ASCII;
Nunpack(lpHead,0x02A2C,5);
Nwrite(lpHead,dwAddress,5);
Nunpack(lpHead,dwLength+5,5);
Nwrite(lpHead,dwAddress+5,5);
// 23.05.98 cg, optimized
Nwrite(lpBuf, dwAddress+10, dwLength);
}
RPL_Push(dwAddress);
return S_ERR_NO;
}
//################ //################
@ -118,6 +172,21 @@ VOID UnmapRom()
//# //#
//################ //################
static WORD CrcPort2(VOID) // 20.02.99 cg, new, calculate fingerprint of port2
{
DWORD dwCount;
DWORD dwFileSize;
WORD wCrc = 0;
if (pbyPort2==NULL) return wCrc; // port2 isn't available
dwFileSize = GetFileSize(hPort2File, &dwCount); // get real filesize
_ASSERT(dwCount == 0); // isn't created by MapPort2()
for (dwCount = 0;dwCount < dwFileSize; ++dwCount)
wCrc = (wCrc >> 4) ^ (((wCrc ^ ((WORD) pbyPort2[dwCount])) & 0xf) * 0x1081);
return wCrc;
}
BOOL MapPort2(LPCSTR szFilename) BOOL MapPort2(LPCSTR szFilename)
{ {
DWORD dwFileSizeLo; DWORD dwFileSizeLo;
@ -128,6 +197,7 @@ BOOL MapPort2(LPCSTR szFilename)
return FALSE; return FALSE;
} }
bPort2Writeable = TRUE; bPort2Writeable = TRUE;
dwPort2Size = 0; // 26.06.98 cg, new, reset size of port2
SetCurrentDirectory(szEmu48Directory); SetCurrentDirectory(szEmu48Directory);
if (bPort2IsShared) if (bPort2IsShared)
@ -175,14 +245,7 @@ BOOL MapPort2(LPCSTR szFilename)
bPort2Writeable = FALSE; bPort2Writeable = FALSE;
return FALSE; return FALSE;
} }
dwPort2Mask = 0; dwPort2Mask = (dwFileSizeLo >> 17) - 1; // 26.06,98 cg, optimized, calculate bank switching mask
dwFileSizeHi = dwFileSizeLo >> 18;
while ((dwFileSizeHi&1)==0)
{
dwPort2Mask = (dwPort2Mask<<1)+1;
dwFileSizeHi>>=1;
}
dwPort2Mask = (dwPort2Mask<<1)+1;
if (bPort2Writeable) if (bPort2Writeable)
hPort2Map = CreateFileMapping(hPort2File, NULL, PAGE_READWRITE, 0, dwFileSizeLo, NULL); hPort2Map = CreateFileMapping(hPort2File, NULL, PAGE_READWRITE, 0, dwFileSizeLo, NULL);
else else
@ -209,6 +272,8 @@ BOOL MapPort2(LPCSTR szFilename)
bPort2Writeable = FALSE; bPort2Writeable = FALSE;
return FALSE; return FALSE;
} }
dwPort2Size = dwFileSizeLo / 2048; // 26.06.98 cg, new, mapping size of port2
if (dwPort2Size > 128) dwPort2Size = 128;
return TRUE; return TRUE;
} }
@ -221,6 +286,7 @@ VOID UnmapPort2()
pbyPort2 = NULL; pbyPort2 = NULL;
hPort2Map = NULL; hPort2Map = NULL;
hPort2File = NULL; hPort2File = NULL;
dwPort2Size = 0; // 26.06.98 cg, new, reset size of port2
dwPort2Mask = 0; dwPort2Mask = 0;
bPort2Writeable = FALSE; bPort2Writeable = FALSE;
return; return;
@ -501,13 +567,14 @@ BOOL OpenDocument(LPCSTR szFilename)
Chipset.Port0 = NULL; Chipset.Port0 = NULL;
Chipset.Port1 = NULL; Chipset.Port1 = NULL;
SetWindowPos(hWnd,NULL,(int)Chipset.wPosX,(int)Chipset.wPosY,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE); // 26.01.98 cg, bugfix, WORD to int conversation failed with negative numbers
SetWindowPos(hWnd,NULL,(short)Chipset.wPosX,(short)Chipset.wPosY,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
if (szCurrentKml == NULL) if (szCurrentKml == NULL)
{ {
if (!DisplayChooseKml(Chipset.type)) if (!DisplayChooseKml(Chipset.type))
{ {
CloseHandle(hFile); // CloseHandle(hFile); // 29.01.98 cg, bugfix, will be close at end of function
goto restore; goto restore;
} }
} }
@ -515,7 +582,7 @@ BOOL OpenDocument(LPCSTR szFilename)
{ {
if (!DisplayChooseKml(Chipset.type)) if (!DisplayChooseKml(Chipset.type))
{ {
CloseHandle(hFile); // CloseHandle(hFile); // 29.01.98 cg, bugfix, will be close at end of function
goto restore; goto restore;
} }
} }
@ -546,6 +613,13 @@ BOOL OpenDocument(LPCSTR szFilename)
if (lBytesRead != Chipset.Port1Size*2048) goto read_err; if (lBytesRead != Chipset.Port1Size*2048) goto read_err;
} }
if (Chipset.wPort2Crc != CrcPort2()) // 21.02.99 cg, new, port2 changed
{
Chipset.HST |= 8; // 21.02.99 cg, new, set Module Pulled
Chipset.SoftInt = TRUE; // 21.02.99 cg, new, set interrupt
bInterrupt = TRUE; // 21.02.99 cg, new
}
lstrcpy(szCurrentFilename, szFilename); lstrcpy(szCurrentFilename, szFilename);
hCurrentFile = hFile; hCurrentFile = hFile;
Map(0x00,0xFF); Map(0x00,0xFF);
@ -556,7 +630,7 @@ BOOL OpenDocument(LPCSTR szFilename)
read_err: read_err:
AbortMessage("This file must be truncated, and cannot be loaded."); AbortMessage("This file must be truncated, and cannot be loaded.");
restore: restore:
if (INVALID_HANDLE_VALUE == hFile) if (INVALID_HANDLE_VALUE != hFile) // 29.01.98 cg, bugfix, close if valid handle
CloseHandle(hFile); CloseHandle(hFile);
RestoreBackup(); RestoreBackup();
ResetBackup(); ResetBackup();
@ -583,6 +657,8 @@ BOOL SaveDocument()
return FALSE; return FALSE;
} }
Chipset.wPort2Crc = CrcPort2(); // 21.02.99 cg, new, save fingerprint of port2
nLength = strlen(szCurrentKml); nLength = strlen(szCurrentKml);
WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL); WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL);
WriteFile(hCurrentFile, szCurrentKml, nLength, &lBytesWritten, NULL); WriteFile(hCurrentFile, szCurrentKml, nLength, &lBytesWritten, NULL);
@ -599,27 +675,31 @@ BOOL SaveDocumentAs(LPCTSTR szFilename)
{ {
HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFile = INVALID_HANDLE_VALUE;
if (hCurrentFile) if (hCurrentFile) // already file in use
{ {
if (lstrcmpi(szFilename, szCurrentFilename)==0) if (lstrcmpi(szFilename, szCurrentFilename)==0)
{ {
hFile = hCurrentFile; hFile = hCurrentFile; // same file, do not open a new one
} }
} }
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE) // not same file, open a new one
{ {
hFile = CreateFile(szFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); hFile = CreateFile(szFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
} }
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
{ {
AbortMessage("This file must be currently used by another instance of Emu48."); AbortMessage("This file must be currently used by another instance of Emu48.");
return FALSE; return FALSE;
} }
lstrcpy(szCurrentFilename, szFilename); if (hCurrentFile) // 02.10.98 cg, previous file in use
hCurrentFile = hFile; {
SetWindowTitle(szCurrentFilename); CloseHandle(hCurrentFile); // 02.10.98 cg, bugfix, close it
UpdateWindowStatus(); }
return SaveDocument(); lstrcpy(szCurrentFilename, szFilename); // save new file name
hCurrentFile = hFile; // and the corresponding handle
SetWindowTitle(szCurrentFilename); // update window title line
UpdateWindowStatus(); // and draw it
return SaveDocument(); // save current content
} }
@ -651,6 +731,8 @@ BOOL RestoreBackup()
{ {
if (!bBackup) return FALSE; if (!bBackup) return FALSE;
ResetDocument(); ResetDocument();
// 02.02.98 cg, moved, need chipset for contrast setting in InitKML()
CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset));
if (!InitKML(szBackupKml,TRUE)) if (!InitKML(szBackupKml,TRUE))
{ {
InitKML(szCurrentKml,TRUE); InitKML(szCurrentKml,TRUE);
@ -667,7 +749,8 @@ BOOL RestoreBackup()
szCurrentFilename[0] = 0; szCurrentFilename[0] = 0;
} }
} }
CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset)); // 02.02.98 cg, removed, done before
// CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset));
Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048); Chipset.Port0 = (LPBYTE)LocalAlloc(0,Chipset.Port0Size*2048);
CopyMemory(Chipset.Port0, BackupChipset.Port0, Chipset.Port0Size*2048); CopyMemory(Chipset.Port0, BackupChipset.Port0, Chipset.Port0Size*2048);
Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048); Chipset.Port1 = (LPBYTE)LocalAlloc(0,Chipset.Port1Size*2048);
@ -808,16 +891,13 @@ BOOL GetSaveObjectFilename()
//# //#
//################ //################
BOOL LoadObject(LPCSTR szFilename) BOOL LoadObject(LPCSTR szFilename) // 11.05.98 cg, changed, separated stack writing part
{ {
HANDLE hFile; HANDLE hFile;
DWORD dwFileSizeLow; DWORD dwFileSizeLow;
DWORD dwFileSizeHigh; DWORD dwFileSizeHigh;
DWORD lBytesRead;
LPBYTE lpBuf; LPBYTE lpBuf;
BOOL bKermit = FALSE; WORD wError;
DWORD dwLength, dwAddress;
DWORD i;
hFile = CreateFile(szFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); hFile = CreateFile(szFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hFile == INVALID_HANDLE_VALUE) return FALSE; if (hFile == INVALID_HANDLE_VALUE) return FALSE;
@ -833,66 +913,22 @@ BOOL LoadObject(LPCSTR szFilename)
CloseHandle(hFile); CloseHandle(hFile);
return FALSE; return FALSE;
} }
ReadFile(hFile, lpBuf+dwFileSizeLow, dwFileSizeLow, &lBytesRead, NULL); ReadFile(hFile, lpBuf+dwFileSizeLow, dwFileSizeLow, &dwFileSizeHigh, NULL);
CloseHandle(hFile); CloseHandle(hFile);
if ((lpBuf[dwFileSizeLow+0]=='H') wError = WriteStack(lpBuf,dwFileSizeLow);
&&(lpBuf[dwFileSizeLow+1]=='P')
&&(lpBuf[dwFileSizeLow+2]=='H')
&&(lpBuf[dwFileSizeLow+3]=='P')
&&(lpBuf[dwFileSizeLow+4]=='4')
&&(lpBuf[dwFileSizeLow+5]=='8')
&&(lpBuf[dwFileSizeLow+6]=='-')) bKermit = TRUE;
for (i=0; i<dwFileSizeLow; i++) if (wError == S_ERR_BINARY)
{ AbortMessage("The HP48 has not enough free memory left to load this binary file.");
BYTE byTwoNibs = lpBuf[i+dwFileSizeLow];
lpBuf[i*2 ] = (BYTE)(byTwoNibs&0xF); if (wError == S_ERR_ASCII)
lpBuf[i*2+1] = (BYTE)(byTwoNibs>>4); AbortMessage("The HP48 has not enough free memory left to load this text file.");
}
if (bKermit == TRUE)
{ // load as binary
dwLength = RPL_ObjectSize(lpBuf+16);
dwAddress = RPL_CreateTemp(dwLength);
if (dwAddress == 0)
{
LocalFree(lpBuf);
AbortMessage("The HP48 has not enough free memory left to load this binary file.");
return FALSE;
}
for (i=0; i<dwLength; i++)
{
Nwrite(lpBuf+i+16, dwAddress+i, 1);
}
}
else
{ // load as string
BYTE lpHead[5];
dwLength = dwFileSizeLow*2;
dwAddress = RPL_CreateTemp(dwLength+10);
if (dwAddress == 0)
{
LocalFree(lpBuf);
AbortMessage("The HP48 has not enough free memory left to load this text file.");
return FALSE;
}
Nunpack(lpHead,0x02A2C,5);
Nwrite(lpHead,dwAddress,5);
Nunpack(lpHead,dwLength+5,5);
Nwrite(lpHead,dwAddress+5,5);
for (i=0; i<dwLength; i++)
{
Nwrite(lpBuf+i, dwAddress+10+i, 1);
}
}
RPL_Push(dwAddress);
LocalFree(lpBuf); LocalFree(lpBuf);
return TRUE; return (wError == S_ERR_NO);
} }
BOOL SaveObject(LPCSTR szFilename) // 11.05.98 cg, changed, separated stack reading part
BOOL SaveObject(LPCSTR szFilename)
{ {
HANDLE hFile; HANDLE hFile;
DWORD lBytesWritten; DWORD lBytesWritten;
@ -914,7 +950,7 @@ BOOL SaveObject(LPCSTR szFilename)
return FALSE; return FALSE;
} }
WriteFile(hFile, "HPHP48-W", 8, &lBytesWritten, NULL); WriteFile(hFile, BINARYHEADER, 8, &lBytesWritten, NULL);
while (dwLength--) while (dwLength--)
{ {
BYTE byByte = Read2(dwAddress); BYTE byByte = Read2(dwAddress);
@ -1042,17 +1078,19 @@ HBITMAP LoadBitmapFile(LPCSTR szFilename)
LPBITMAPFILEHEADER pBmfh; LPBITMAPFILEHEADER pBmfh;
LPBITMAPINFO pBmi; LPBITMAPINFO pBmi;
if (hRomFile == NULL) return NULL; // 17.10.97 cg, bugfix, line moved and error case is NULL
SetCurrentDirectory(szEmu48Directory); SetCurrentDirectory(szEmu48Directory);
hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
SetCurrentDirectory(szCurrentDirectory); SetCurrentDirectory(szCurrentDirectory);
if (hRomFile == INVALID_HANDLE_VALUE) return NULL; // 19.01.98 cg, bugfix, opend with GENERIC_READ -> PAGE_READONLY
hMap = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, NULL); hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (hMap == NULL) if (hMap == NULL)
{ {
CloseHandle(hFile); CloseHandle(hFile);
return NULL; return NULL;
} }
pbyFile = MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0, 0); // 19.01.98 cg, bugfix, opend with GENERIC_READ -> PAGE_READONLY -> FILE_MAP_READ
pbyFile = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (pbyFile == NULL) if (pbyFile == NULL)
{ {
CloseHandle(hMap); CloseHandle(hMap);
@ -1065,8 +1103,10 @@ HBITMAP LoadBitmapFile(LPCSTR szFilename)
if (pBmfh->bfType != 0x4D42) goto quit; // "BM" if (pBmfh->bfType != 0x4D42) goto quit; // "BM"
pBmi = (LPBITMAPINFO)(pbyFile+sizeof(BITMAPFILEHEADER)); pBmi = (LPBITMAPINFO)(pbyFile+sizeof(BITMAPFILEHEADER));
_ASSERT(hPalette == NULL); // 11.09.98 cg, resource free
hPalette = CreateBIPalette(&pBmi->bmiHeader); hPalette = CreateBIPalette(&pBmi->bmiHeader);
SelectPalette(hWindowDC, hPalette, FALSE); // 11.09.98 cg, save old palette
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
RealizePalette(hWindowDC); RealizePalette(hWindowDC);
if (FALSE&&(pBmi->bmiHeader.biBitCount <= 8)) if (FALSE&&(pBmi->bmiHeader.biBitCount <= 8))

164
sources/Emu48/KEYBOARD.C Normal file
View file

@ -0,0 +1,164 @@
/*
* keyboard.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
static WORD Keyboard_GetIR(VOID) // 13.02.99 cg, make function static
{
WORD r = 0;
if (Chipset.out==0) return 0;
if (Chipset.out&0x001) r|=Chipset.Keyboard_Row[0];
if (Chipset.out&0x002) r|=Chipset.Keyboard_Row[1];
if (Chipset.out&0x004) r|=Chipset.Keyboard_Row[2];
if (Chipset.out&0x008) r|=Chipset.Keyboard_Row[3];
if (Chipset.out&0x010) r|=Chipset.Keyboard_Row[4];
if (Chipset.out&0x020) r|=Chipset.Keyboard_Row[5];
if (Chipset.out&0x040) r|=Chipset.Keyboard_Row[6];
if (Chipset.out&0x080) r|=Chipset.Keyboard_Row[7];
if (Chipset.out&0x100) r|=Chipset.Keyboard_Row[8];
return r;
}
VOID ScanKeyboard(BOOL bReset) // 02.09.98 cg, changed, add flag for key state reset
{
// 02.09.98 cg, new, changed implementation
// bReset = TRUE -> Reset Chipset.in interrupt state register
// FALSE -> generate interrupt only for new pressed keys
EnterCriticalSection(&csKeyLock); // synchronize
{
BOOL bKbdInt;
WORD wOldIn = Chipset.in; // save old Chipset.in state
// 26.02.99 cg, bugfix, update KDN bit
UpdateKdnBit();
Chipset.dwKdnCycles = Chipset.cycles;
// update Chipset.in register
Chipset.in = Keyboard_GetIR() | Chipset.IR15X;
// interrrupt for any new pressed keys ?
bKbdInt = ((Chipset.in & (Chipset.in ^ wOldIn)) != 0) || bReset;
// 01.03.99 cg, bugfix, update keyboard interrupt pending flag
Chipset.intd = Chipset.intd || (bKbdInt && !Chipset.intk);
// 28.02.99 cg, changed, keyboard interrupt enabled
bKbdInt = bKbdInt && (Chipset.intk || Chipset.IR15X != 0) && Chipset.inte;
if (Chipset.in != 0) // any key pressed
{
if (bKbdInt) // interrupt enabled
{
Chipset.SoftInt = TRUE; // interrupt request
bInterrupt = TRUE; // exit emulation loop
}
if (Chipset.Shutdn) // cpu sleeping
ResumeThread(hThread); // wake up
}
else
{
Chipset.intd = FALSE; // 01.03.99 cg, bugfix, no keyboard interrupt pending
}
}
LeaveCriticalSection(&csKeyLock);
#if 0
// 02.09.98 cg, removed
// 11.06.98 cg, new, changed implementation
// keyboard interrupt enabled
BOOL bKbdInt = (Chipset.intk || Chipset.IR15X != 0) && Chipset.inte && Chipset.in == 0;
// update Chipset.in register
Chipset.in = Keyboard_GetIR() | Chipset.IR15X;
if (Chipset.in != 0) // call interrupt ?
{
if (bKbdInt) // interrupt enabled
{
Chipset.SoftInt = TRUE; // interrupt request
bInterrupt = TRUE; // exit emulation loop
}
if (Chipset.Shutdn) // cpu sleeping
ResumeThread(hThread); // wake up
}
#endif
#if 0
// 11.06.98 cg, removed
WORD IR = Keyboard_GetIR();
Chipset.in = IR | Chipset.IR15X;
if (Chipset.IR15X)
{
if (Chipset.inte)
{
// PatBlt(hWindowDC,0,0,8,8,DSTINVERT);
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
if (Chipset.Shutdn)
{
// PatBlt(hWindowDC,8,0,8,8,DSTINVERT);
Chipset.Shutdn = FALSE; // Prevent another ResumeThread
ResumeThread(hThread);
}
}
if (IR != 0)
{
if ((Chipset.inte) && (Chipset.intk))
{
// PatBlt(hWindowDC,0,8,8,8,DSTINVERT);
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
if (Chipset.Shutdn)
{
// PatBlt(hWindowDC,8,8,8,8,DSTINVERT);
Chipset.Shutdn = FALSE; // Prevent another ResumeThread
ResumeThread(hThread);
}
}
#endif
return;
}
VOID KeyboardEvent(BOOL bPress, UINT out, UINT in)
{
if (nState != 0) // not in running state
return; // ignore key
if (in == 0x8000) // ON key ?
{
Chipset.IR15X = bPress?0x8000:0x0000; // refresh special ON key flag
}
else
{
_ASSERT(out<9);
if (bPress) // key pressed
{
// 11.06.98 cg, removed, do interrupt handling in ScanKeyboard()
// if (((Chipset.Keyboard_Row[out]&in) == 0) && (Chipset.inte==FALSE) && (Chipset.intk))
// Chipset.intd = TRUE;
Chipset.Keyboard_Row[out] |= in; // set key marker in keyboard row
}
else
Chipset.Keyboard_Row[out] &= (~in); // clear key marker in keyboard row
}
ScanKeyboard(FALSE); // 02.09.98 cg, changed, update Chipset.in register
bKeySlow = FALSE; // 18.11.98 cg, new, break key slow down
Sleep(50); // 28.09.98 cg, hold key state for a definite time
return;
}

View file

@ -116,6 +116,9 @@ static TokenId eIsBlock[] =
static BOOL bClicking = FALSE; static BOOL bClicking = FALSE;
static UINT uButtonClicked = 0; static UINT uButtonClicked = 0;
static BOOL bPressed = FALSE; // 01.10.97 cg, no key pressed
static UINT uLastPressedKey = 0; // 01.10.97 cg, var for last pressed key
//################ //################
//# //#
//# Compilation Result //# Compilation Result
@ -336,7 +339,8 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l
if (wParam == IDC_UPDATE) if (wParam == IDC_UPDATE)
{ {
DestroyKmlList(); DestroyKmlList();
GetDlgItemText(hDlg,IDC_EMU48DIR,szEmu48Directory,260); // 01.02.98 cg, calculate size of buffer
GetDlgItemText(hDlg,IDC_EMU48DIR,szEmu48Directory,sizeof(szEmu48Directory));
CreateKmlList(); CreateKmlList();
hList = GetDlgItem(hDlg,IDC_KMLSCRIPT); hList = GetDlgItem(hDlg,IDC_KMLSCRIPT);
SendMessage(hList, CB_RESETCONTENT, 0, 0); SendMessage(hList, CB_RESETCONTENT, 0, 0);
@ -352,7 +356,8 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l
} }
if (wParam == IDOK) if (wParam == IDOK)
{ {
GetDlgItemText(hDlg,IDC_EMU48DIR,szEmu48Directory,260); // 01.02.98 cg, calculate size of buffer
GetDlgItemText(hDlg,IDC_EMU48DIR,szEmu48Directory,sizeof(szEmu48Directory));
hList = GetDlgItem(hDlg,IDC_KMLSCRIPT); hList = GetDlgItem(hDlg,IDC_KMLSCRIPT);
nIndex = SendMessage(hList, CB_GETCURSEL, 0, 0); nIndex = SendMessage(hList, CB_GETCURSEL, 0, 0);
nIndex = SendMessage(hList, CB_GETITEMDATA, nIndex, 0); nIndex = SendMessage(hList, CB_GETITEMDATA, nIndex, 0);
@ -618,8 +623,7 @@ loop:
if (eToken != TOK_EOL) if (eToken != TOK_EOL)
{ {
PrintfToLog("%i: Too many parameters (%i expected).", nLexLine, j); PrintfToLog("%i: Too many parameters (%i expected).", nLexLine, j);
LocalFree(pLine); goto errline; // 09.03.99 cg, bugfix, free memory of arguments
return NULL;
} }
return pLine; return pLine;
} }
@ -628,8 +632,7 @@ loop:
if (eToken != TOK_INTEGER) if (eToken != TOK_INTEGER)
{ {
PrintfToLog("%i: Parameter %i of %s must be an integer.", nLexLine, j+1, pLexToken[i].szName); PrintfToLog("%i: Parameter %i of %s must be an integer.", nLexLine, j+1, pLexToken[i].szName);
LocalFree(pLine); goto errline; // 09.03.99 cg, bugfix, free memory of arguments
return NULL;
} }
pLine->nParam[j++] = nLexInteger; pLine->nParam[j++] = nLexInteger;
nParams >>= 3; nParams >>= 3;
@ -640,14 +643,28 @@ loop:
if (eToken != TOK_STRING) if (eToken != TOK_STRING)
{ {
PrintfToLog("%i: Parameter %i of %s must be a string.", nLexLine, j+1, pLexToken[i].szName); PrintfToLog("%i: Parameter %i of %s must be a string.", nLexLine, j+1, pLexToken[i].szName);
LocalFree(pLine); goto errline; // 09.03.99 cg, bugfix, free memory of arguments
return NULL;
} }
pLine->nParam[j++] = (DWORD)szLexString; pLine->nParam[j++] = (DWORD)szLexString;
nParams >>= 3; nParams >>= 3;
goto loop; goto loop;
} }
AddToLog("Oops..."); AddToLog("Oops...");
errline:
// 09.03.99 cg, bugfix, free memory of all string arguments
// if last argument was string, free it
if (eToken == TOK_STRING) LocalFree(szLexString);
nParams = pLexToken[i].nParams; // get argument types of command
for (i=0; i<j; i++) // handle all scanned arguments
{
if ((nParams&7) == TYPE_STRING) // string type
{
LocalFree((LPVOID)pLine->nParam[i]);
}
nParams >>= 3; // next argument type
}
// 09.03.99 cg, end of bugfix
LocalFree(pLine); LocalFree(pLine);
return NULL; return NULL;
} }
@ -721,12 +738,15 @@ static Line* ParseLines()
if (IsBlock(eToken)) nLevel++; if (IsBlock(eToken)) nLevel++;
if (eToken == TOK_INCLUDE) if (eToken == TOK_INCLUDE)
{ {
eToken = Lex(LEX_PARAM); LPSTR szFilename; // 11.09.98 cg
if (eToken != TOK_STRING) eToken = Lex(LEX_PARAM); // get include parameter in 'szLexString'
if (eToken != TOK_STRING) // not a string (token don't begin with ")
{ {
AddToLog("Include: string expected as parameter."); AddToLog("Include: string expected as parameter.");
FatalError(); // 09.03.99 cg, moved from abort part
goto abort; goto abort;
} }
szFilename = szLexString; // 11.09.98 cg, save pointer to allocated memory
if (pFirst) if (pFirst)
{ {
pLine->pNext = IncludeLines(szLexString); pLine->pNext = IncludeLines(szLexString);
@ -735,6 +755,9 @@ static Line* ParseLines()
{ {
pLine = pFirst = IncludeLines(szLexString); pLine = pFirst = IncludeLines(szLexString);
} }
LocalFree(szFilename); // 11.09.98 cg, bugfix, free memory
if (pLine == NULL) // 09.03.99 cg, bugfix, parsing error
goto abort;
while (pLine->pNext) pLine=pLine->pNext; while (pLine->pNext) pLine=pLine->pNext;
continue; continue;
} }
@ -758,6 +781,8 @@ static Line* ParseLines()
{ {
pLine = pFirst = ParseLine(eToken); pLine = pFirst = ParseLine(eToken);
} }
if (pLine == NULL) // 09.03.99 cg, bugfix, parsing error
goto abort;
} }
if (nLinesIncludeLevel) if (nLinesIncludeLevel)
{ {
@ -768,10 +793,9 @@ static Line* ParseLines()
abort: abort:
if (pFirst) if (pFirst)
{ {
pLine->pNext = NULL; // pLine->pNext = NULL; // 09.03.99 cg, bugfix, pLine == NULL !
FreeLines(pFirst); FreeLines(pFirst);
} }
FatalError();
return NULL; return NULL;
} }
@ -822,6 +846,12 @@ static Block* ParseBlock(TokenId eType)
pBlock->pFirstLine = ParseLines(); pBlock->pFirstLine = ParseLines();
if (pBlock->pFirstLine == NULL) // 09.03.99 cg, bugfix, break on ParseLines error
{
LocalFree(pBlock);
pBlock = NULL;
}
return pBlock; return pBlock;
} }
@ -892,16 +922,22 @@ static Block* ParseBlocks()
{ {
if (eToken == TOK_INCLUDE) if (eToken == TOK_INCLUDE)
{ {
eToken = Lex(LEX_PARAM); LPSTR szFilename; // 11.09.98 cg
if (eToken != TOK_STRING) eToken = Lex(LEX_PARAM); // get include parameter in 'szLexString'
if (eToken != TOK_STRING) // not a string (token don't begin with ")
{ {
AddToLog("Include: string expected as parameter."); AddToLog("Include: string expected as parameter.");
FatalError(); // 09.03.99 cg, moved from abort part
goto abort; goto abort;
} }
szFilename = szLexString; // 11.09.98 cg, save pointer to allocated memory
if (pFirst) if (pFirst)
pBlock = pBlock->pNext = IncludeBlocks(szLexString); pBlock = pBlock->pNext = IncludeBlocks(szLexString);
else else
pBlock = pFirst = IncludeBlocks(szLexString); pBlock = pFirst = IncludeBlocks(szLexString);
LocalFree(szFilename); // 11.09.98 cg, bugfix, free memory
if (pBlock == NULL) // 09.03.99 cg, bugfix, parsing error
goto abort;
while (pBlock->pNext) pBlock=pBlock->pNext; while (pBlock->pNext) pBlock=pBlock->pNext;
continue; continue;
} }
@ -912,6 +948,7 @@ static Block* ParseBlocks()
if (pBlock == NULL) if (pBlock == NULL)
{ {
AddToLog("Invalid block."); AddToLog("Invalid block.");
FatalError(); // 09.03.99 cg, moved from abort part
goto abort; goto abort;
} }
} }
@ -919,7 +956,6 @@ static Block* ParseBlocks()
return pFirst; return pFirst;
abort: abort:
if (pFirst) FreeBlocks(pFirst); if (pFirst) FreeBlocks(pFirst);
FatalError();
return NULL; return NULL;
} }
@ -1040,7 +1076,9 @@ static Line* InitLcd(Block* pBlock)
nLcdY = pLine->nParam[1]; nLcdY = pLine->nParam[1];
break; break;
case TOK_ZOOM: case TOK_ZOOM:
bLcdDoubled = (pLine->nParam[0]==2); nLcdDoubled = pLine->nParam[0]; // 24.08.98 cg, changed var type
if (nLcdDoubled != 1 && nLcdDoubled != 2 && nLcdDoubled != 4)
nLcdDoubled = 1;
break; break;
case TOK_COLOR: case TOK_COLOR:
SetLcdColor(pLine->nParam[0],pLine->nParam[1],pLine->nParam[2],pLine->nParam[3]); SetLcdColor(pLine->nParam[0],pLine->nParam[1],pLine->nParam[2],pLine->nParam[3]);
@ -1277,22 +1315,25 @@ static VOID FreeLines(Line* pLine)
Line* pThisLine = pLine; Line* pThisLine = pLine;
UINT i = 0; UINT i = 0;
DWORD nParams; DWORD nParams;
while (pLexToken[i].nLen) while (pLexToken[i].nLen) // search in all token definitions
{ {
// break when token definition found
if (pLexToken[i].eId == pLine->eCommand) break; if (pLexToken[i].eId == pLine->eCommand) break;
i++; i++; // next token definition
} }
nParams = pLexToken[i].nParams; nParams = pLexToken[i].nParams; // get argument types of command
i = 0; i = 0; // first parameter
while ((nParams&7)) while ((nParams&7)) // argument left
{ {
if ((nParams&7) == TYPE_STRING) if ((nParams&7) == TYPE_STRING) // string type
{ {
LocalFree((LPVOID)pLine->nParam[i++]); // 09.03.99 cg, bugfix, free string without incr. parameter buffer
LocalFree((LPVOID)pLine->nParam[i]);
} }
nParams >>= 3; i++; // 09.03.99 cg, bugfix, incr. parameter buffer index
nParams >>= 3; // next argument type
} }
pLine = pLine->pNext; pLine = pLine->pNext; // get next line
LocalFree(pThisLine); LocalFree(pThisLine);
} }
return; return;
@ -1323,7 +1364,11 @@ VOID KillKML()
DestroyMainBitmap(); DestroyMainBitmap();
if (hPalette) if (hPalette)
{ {
DeleteObject(hPalette); BOOL err;
// 11.09.98, bugfix, unlock hPalette
if (hWindowDC) SelectPalette(hWindowDC, hOldPalette, FALSE);
err = DeleteObject(hPalette);
_ASSERT(err != FALSE); // 11.09.98 cg, freed resource memory
hPalette = NULL; hPalette = NULL;
} }
bClicking = FALSE; bClicking = FALSE;
@ -1408,84 +1453,89 @@ static VOID DrawButton(UINT nId)
UINT x0 = pButton[nId].nOx; UINT x0 = pButton[nId].nOx;
UINT y0 = pButton[nId].nOy; UINT y0 = pButton[nId].nOy;
switch (pButton[nId].nType) EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{ {
case 0: switch (pButton[nId].nType)
if (pButton[nId].bDown)
{ {
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, pButton[nId].nDx, pButton[nId].nDy, SRCCOPY); case 0:
if (pButton[nId].bDown)
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, pButton[nId].nDx, pButton[nId].nDy, SRCCOPY);
}
else
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
case 1:
if (pButton[nId].bDown)
{
UINT x1 = x0+pButton[nId].nCx-1;
UINT y1 = y0+pButton[nId].nCy-1;
BitBlt(hWindowDC, x0+3,y0+3,pButton[nId].nCx-5,pButton[nId].nCy-5,hMainDC,x0+2,y0+2,SRCCOPY);
SelectObject(hWindowDC, GetStockObject(BLACK_PEN));
MoveToEx(hWindowDC, x0,y0, NULL); LineTo(hWindowDC, x1,y0);
MoveToEx(hWindowDC, x0,y0, NULL); LineTo(hWindowDC, x0,y1);
SelectObject(hWindowDC, GetStockObject(WHITE_PEN));
MoveToEx(hWindowDC, x1,y0, NULL); LineTo(hWindowDC, x1,y1);
MoveToEx(hWindowDC, x0,y1, NULL); LineTo(hWindowDC, x1+1,y1);
}
else
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
case 2:
break;
case 3:
if (pButton[nId].bDown)
{
PatBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, DSTINVERT);
}
else
{
RECT Rect;
Rect.left = x0;
Rect.right = x0 + pButton[nId].nCx;
Rect.top = y0;
Rect.bottom = y0 + pButton[nId].nCy;
InvalidateRect(hWnd, &Rect, 0);
}
break;
case 4:
if (pButton[nId].bDown)
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
else
{
RECT Rect;
Rect.left = x0;
Rect.right = x0 + pButton[nId].nCx;
Rect.top = y0;
Rect.bottom = y0 + pButton[nId].nCy;
InvalidateRect(hWnd, &Rect, 0);
}
break;
case 5:
if (pButton[nId].bDown)
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, pButton[nId].nDx, pButton[nId].nDy, SRCCOPY);
}
else
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
default:
if (pButton[nId].bDown)
PatBlt(hWindowDC, x0,y0, pButton[nId].nCx, pButton[nId].nCy, BLACKNESS);
else
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
} }
else GdiFlush(); // 22.01.98 cg
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
case 1:
if (pButton[nId].bDown)
{
UINT x1 = x0+pButton[nId].nCx-1;
UINT y1 = y0+pButton[nId].nCy-1;
BitBlt(hWindowDC, x0+3,y0+3,pButton[nId].nCx-5,pButton[nId].nCy-5,hMainDC,x0+2,y0+2,SRCCOPY);
SelectObject(hWindowDC, GetStockObject(BLACK_PEN));
MoveToEx(hWindowDC, x0,y0, NULL); LineTo(hWindowDC, x1,y0);
MoveToEx(hWindowDC, x0,y0, NULL); LineTo(hWindowDC, x0,y1);
SelectObject(hWindowDC, GetStockObject(WHITE_PEN));
MoveToEx(hWindowDC, x1,y0, NULL); LineTo(hWindowDC, x1,y1);
MoveToEx(hWindowDC, x0,y1, NULL); LineTo(hWindowDC, x1+1,y1);
}
else
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
case 2:
break;
case 3:
if (pButton[nId].bDown)
{
PatBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, DSTINVERT);
}
else
{
RECT Rect;
Rect.left = x0;
Rect.right = x0 + pButton[nId].nCx;
Rect.top = y0;
Rect.bottom = y0 + pButton[nId].nCy;
InvalidateRect(hWnd, &Rect, 0);
}
break;
case 4:
if (pButton[nId].bDown)
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
else
{
RECT Rect;
Rect.left = x0;
Rect.right = x0 + pButton[nId].nCx;
Rect.top = y0;
Rect.bottom = y0 + pButton[nId].nCy;
InvalidateRect(hWnd, &Rect, 0);
}
break;
case 5:
if (pButton[nId].bDown)
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, pButton[nId].nDx, pButton[nId].nDy, SRCCOPY);
}
else
{
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
}
break;
default:
if (pButton[nId].bDown)
PatBlt(hWindowDC, x0,y0, pButton[nId].nCx, pButton[nId].nCy, BLACKNESS);
else
BitBlt(hWindowDC, x0, y0, pButton[nId].nCx, pButton[nId].nCy, hMainDC, x0, y0, SRCCOPY);
} }
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return; return;
} }
@ -1555,6 +1605,20 @@ static VOID ReleaseButtonById(UINT nId)
return; return;
} }
static VOID ReleaseAllButtons(VOID) // 01.10.97 cg, new, release all buttons
{
UINT i;
for (i=0; i<nButtons; i++) // scan all buttons
{
if (pButton[i].bDown) // button pressed
ReleaseButton(i); // release button
}
bPressed = FALSE; // key not pressed
bClicking = FALSE; // var uButtonClicked not valid (no virtual or nohold key)
uButtonClicked = 0; // set var to default
}
VOID RefreshButtons() VOID RefreshButtons()
{ {
UINT i; UINT i;
@ -1576,24 +1640,29 @@ VOID DrawAnnunciator(UINT nId, BOOL bOn)
{ {
nId--; nId--;
if (nId>=6) return; if (nId>=6) return;
if (bOn) EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{ {
BitBlt(hWindowDC, if (bOn)
pAnnunciator[nId].nOx, pAnnunciator[nId].nOy, {
pAnnunciator[nId].nCx, pAnnunciator[nId].nCy, BitBlt(hWindowDC,
hMainDC, pAnnunciator[nId].nOx, pAnnunciator[nId].nOy,
pAnnunciator[nId].nDx, pAnnunciator[nId].nDy, pAnnunciator[nId].nCx, pAnnunciator[nId].nCy,
SRCCOPY); hMainDC,
} pAnnunciator[nId].nDx, pAnnunciator[nId].nDy,
else SRCCOPY);
{ }
BitBlt(hWindowDC, else
pAnnunciator[nId].nOx, pAnnunciator[nId].nOy, {
pAnnunciator[nId].nCx, pAnnunciator[nId].nCy, BitBlt(hWindowDC,
hMainDC, pAnnunciator[nId].nOx, pAnnunciator[nId].nOy,
pAnnunciator[nId].nOx, pAnnunciator[nId].nOy, pAnnunciator[nId].nCx, pAnnunciator[nId].nCy,
SRCCOPY); hMainDC,
pAnnunciator[nId].nOx, pAnnunciator[nId].nOy,
SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
} }
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return; return;
} }
@ -1622,27 +1691,41 @@ VOID MouseButtonDownAt(UINT nFlags, DWORD x, DWORD y)
{ {
if (pButton[i].dwFlags&BUTTON_NOHOLD) if (pButton[i].dwFlags&BUTTON_NOHOLD)
{ {
bClicking = TRUE; if (nFlags&MK_LBUTTON) // 01.10.97 cg, use only with left mouse button
uButtonClicked = i; {
pButton[i].bDown = TRUE; bClicking = TRUE;
DrawButton(i); uButtonClicked = i;
pButton[i].bDown = TRUE;
DrawButton(i);
}
return; return;
} }
if (pButton[i].dwFlags&BUTTON_VIRTUAL) if (pButton[i].dwFlags&BUTTON_VIRTUAL)
{ {
if (!(nFlags&MK_LBUTTON)) // 01.10.97 cg, use only with left mouse button
return;
bClicking = TRUE; bClicking = TRUE;
uButtonClicked = i; uButtonClicked = i;
} }
bPressed = TRUE; // 01.10.97 cg, key pressed
uLastPressedKey = i; // 01.10.97 cg, save pressed key
PressButton(i); PressButton(i);
return; return;
} }
} }
UNREFERENCED_PARAMETER(nFlags);
} }
VOID MouseButtonUpAt(UINT nFlags, DWORD x, DWORD y) VOID MouseButtonUpAt(UINT nFlags, DWORD x, DWORD y)
{ {
UINT i; UINT i;
// begin with patch
if (bPressed) // 01.10.97 cg, emulator key pressed
{
ReleaseAllButtons(); // 01.10.97 cg, release all buttons
return;
}
// continue with original part to look for nohold buttons
for (i=0; i<nButtons; i++) for (i=0; i<nButtons; i++)
{ {
if (ClipButton(x,y,i)) if (ClipButton(x,y,i))
@ -1660,8 +1743,13 @@ VOID MouseButtonUpAt(UINT nFlags, DWORD x, DWORD y)
VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y) VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y)
{ {
if (!bClicking) return; // begin with patch
if (!(nFlags&MK_LBUTTON)) return; if (!(nFlags&MK_LBUTTON)) return; // left mouse key not pressed -> quit
if ((bPressed) && !(ClipButton(x,y,uLastPressedKey))) // 01.10.97 cg, not on last pressed key
ReleaseAllButtons(); // 01.10.97 cg, release all buttons
if (!bClicking) return; // normal emulation key -> quit
// continue with original part
if (pButton[uButtonClicked].dwFlags&BUTTON_NOHOLD) if (pButton[uButtonClicked].dwFlags&BUTTON_NOHOLD)
{ {
if (ClipButton(x,y, uButtonClicked) != pButton[uButtonClicked].bDown) if (ClipButton(x,y, uButtonClicked) != pButton[uButtonClicked].bDown)

1377
sources/Emu48/MOPS.C Normal file

File diff suppressed because it is too large Load diff

2405
sources/Emu48/OPCODES.H Normal file

File diff suppressed because it is too large Load diff

View file

@ -6,7 +6,7 @@
* Copyright (C) 1995 Sebastien Carlier * Copyright (C) 1995 Sebastien Carlier
* *
*/ */
#pragma warning(disable:4244) // #pragma warning(disable:4244)
// Fields start and length // Fields start and length
static UINT F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0}; static UINT F_s[16] = {0/*P*/,0,2,0,15,3,0,0,0,0,0,0,0,0,0,0};
@ -24,14 +24,13 @@ static UINT F_l[16] = {1,1/*P+1*/,1,3,1,12,2,16,0,0,0,0,0,0,0,5};
#define NFor(a, b, f) Nor((a)+F_s[f], (b)+F_s[f], F_l[f]) #define NFor(a, b, f) Nor((a)+F_s[f], (b)+F_s[f], F_l[f])
#define NFzero(a,f) memset((a)+F_s[f], 0, F_l[f]) #define NFzero(a,f) memset((a)+F_s[f], 0, F_l[f])
#define NFpack(a, f) Npack((a)+F_s[f], F_l[f]) #define NFpack(a, f) Npack((a)+F_s[f], F_l[f])
#define NFinc(a, f) Ninc((a)+F_s[f], F_l[f]) #define NFinc(a, f) Ninc(a, F_l[f], F_s[f]) // 24.03.98 cg, changed
#define NFdec(a, f) Ndec((a)+F_s[f], F_l[f]) #define NFdec(a, f) Ndec(a, F_l[f], F_s[f]) // 24.03.98 cg, changed
#define NFnot(a, f) Nnot((a)+F_s[f], F_l[f]) #define NFnot(a, f) Nnot((a)+F_s[f], F_l[f])
#define NFneg(a, f) Nneg((a)+F_s[f], F_l[f]) #define NFneg(a, f) Nneg((a)+F_s[f], F_l[f])
#define NFsl(a, f) Nsl((a)+F_s[f], F_l[f]) #define NFsl(a, f) Nsl((a)+F_s[f], F_l[f])
#define NFsr(a, f) Nsr((a)+F_s[f], F_l[f]) #define NFsr(a, f) Nsr((a)+F_s[f], F_l[f])
#define NFsrb(a, f) Nsrb((a)+F_s[f], F_l[f]) #define NFsrb(a, f) Nsrb((a)+F_s[f], F_l[f])
#define NFdbl(a, f) Ndbl((a)+F_s[f], F_l[f])
#define TFe(a, b, f) Te((a)+F_s[f], (b)+F_s[f], F_l[f]) #define TFe(a, b, f) Te((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFa(a, b, f) Ta((a)+F_s[f], (b)+F_s[f], F_l[f]) #define TFa(a, b, f) Ta((a)+F_s[f], (b)+F_s[f], F_l[f])
#define TFb(a, b, f) Tb((a)+F_s[f], (b)+F_s[f], F_l[f]) #define TFb(a, b, f) Tb((a)+F_s[f], (b)+F_s[f], F_l[f])
@ -81,30 +80,44 @@ static __inline void Nxchg(BYTE *a, BYTE *b, UINT s)
memcpy(a, X, s); memcpy(a, X, s);
} }
static __inline void Ninc(BYTE *a, UINT s) // 24.03.98 cg, changed, new implementation
static __inline void Ninc(BYTE *a, UINT s, UINT d)
{ {
UINT i; UINT i;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
if (Chipset.mode_dec)
for (i=d; i<s+d; ++i)
{ {
for (i=0; i<s; i++) a[i&0xf]++;
if (a[i&0xf] < cBase)
{ {
a[i]++; Chipset.carry = FALSE;
if (a[i]<10) { Chipset.carry=FALSE; return; } return;
a[i]-=10;
} }
a[i&0xf] -= cBase;
} }
else Chipset.carry = TRUE;
{
for (i=0; i<s; i++)
{
a[i]++;
if (a[i]<16) { Chipset.carry=FALSE; return; }
a[i]-=16;
}
}
Chipset.carry=TRUE;
} }
// 24.03.98 cg, end of new implementation
// 15.02.99 cg, new function
static __inline void Ninc16(BYTE *a, UINT s, UINT d)
{
UINT i;
for (i=d; i<s+d; ++i)
{
a[i&0xf]++;
if (a[i&0xf] < 16)
{
Chipset.carry = FALSE;
return;
}
a[i&0xf] -= 16;
}
Chipset.carry = TRUE;
}
// 15.02.98 cg, end of new function
static __inline void Nincx(BYTE *a, UINT s) static __inline void Nincx(BYTE *a, UINT s)
{ {
@ -119,141 +132,110 @@ static __inline void Nincx(BYTE *a, UINT s)
Chipset.carry=TRUE; Chipset.carry=TRUE;
} }
static __inline void Ndec(BYTE *a, UINT s) // 24.03.98 cg, changed, new implementation
static __inline void Ndec(BYTE *a, UINT s, UINT d)
{ {
UINT i; UINT i;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
if (Chipset.mode_dec)
for (i=d; i<s+d; ++i)
{ {
for (i=0; i<s; i++) a[i&0xf]--;
if (a[i&0xf] < cBase)
{ {
a[i]--; Chipset.carry = FALSE;
if (a[i]<10) { Chipset.carry=FALSE; return; } return;
a[i] += 10;
}
}
else
{
for (i=0; i<s; i++)
{
a[i]--;
if (a[i]<16) { Chipset.carry=FALSE; return; }
a[i] += 16;
} }
a[i&0xf] += cBase;
} }
Chipset.carry = TRUE; Chipset.carry = TRUE;
} }
// 24.03.98 cg, end of new implementation
// 15.02.99 cg, new function
static __inline void Ndec16(BYTE *a, UINT s, UINT d)
{
UINT i;
for (i=d; i<s+d; ++i)
{
a[i&0xf]--;
if (a[i&0xf] < 16)
{
Chipset.carry = FALSE;
return;
}
a[i&0xf] += 16;
}
Chipset.carry = TRUE;
}
// 15.02.98 cg, end of new function
// 25.03.98 cg, optimized, new implementation
static __inline void Nadd(BYTE *a, BYTE *b, UINT s) static __inline void Nadd(BYTE *a, BYTE *b, UINT s)
{ {
UINT i; UINT i;
BYTE c = 0; BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
if (Chipset.mode_dec)
{
for (i=0; i<s; i++)
{
a[i] += b[i] + c;
if (a[i]>=10) { a[i]-=10; c=1; } else c=0;
}
}
else
{
for (i=0; i<s; i++)
{
a[i] += (BYTE)(b[i]+c);
if (a[i]>=16) { a[i]-=16; c=1; } else c=0;
}
}
if (c==1)
Chipset.carry=TRUE;
else
Chipset.carry=FALSE;
}
static __inline void Ndbl(BYTE *a, UINT s) for (i=0; i<s; ++i)
{
UINT i;
BYTE b[16];
BYTE c = 0;
if (Chipset.mode_dec)
{ {
memcpy(b, a, s); a[i] += b[i] + c;
for (i=0; i<s; i++) if (a[i] >= cBase)
{ {
a[i] += b[i] + c; a[i] -= cBase;
if (a[i]>=10) { a[i]-=10; c=1; } else c=0; c = 1;
} }
else
c = 0;
} }
else Chipset.carry = (c==1);
{
memcpy(b, a, s);
for (i=0; i<s; i++)
{
a[i] += (BYTE)(b[i]+c);
if (a[i]>=16) { a[i]-=16; c=1; } else c=0;
}
}
if (c==1)
Chipset.carry=TRUE;
else
Chipset.carry=FALSE;
} }
// 25.03.98 cg, end of new implementation
// 25.03.98 cg, optimized, new implementation
static __inline void Nsub(BYTE *a, BYTE *b, UINT s) static __inline void Nsub(BYTE *a, BYTE *b, UINT s)
{ {
UINT i; UINT i;
BYTE c = 0; BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
if (Chipset.mode_dec) for (i=0; i<s; ++i)
{ {
for (i=0; i<s; i++) a[i] -= b[i] + c;
if (a[i] >= cBase)
{ {
a[i] -= (BYTE)(b[i]+c); a[i] += cBase;
if (a[i]>=10) { a[i]+=10; c=1; } else c=0; c = 1;
} }
else
c = 0;
} }
else Chipset.carry = (c==1);
{
for (i=0; i<s; i++)
{
a[i] -= (BYTE)(b[i]+c);
if (a[i]>=16) { a[i]+=16; c=1; } else c=0;
}
}
if (c==1)
Chipset.carry=TRUE;
else
Chipset.carry=FALSE;
} }
// 25.03.98 cg, end of new implementation
// 25.03.98 cg, optimized, new implementation
static __inline void Nrsub(BYTE *a, BYTE *b, UINT s) static __inline void Nrsub(BYTE *a, BYTE *b, UINT s)
{ {
UINT i; UINT i;
BYTE c = 0; BYTE c = 0;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
if (Chipset.mode_dec)
for (i=0; i<s; ++i)
{ {
for (i=0; i<s; i++) a[i] = b[i] - (a[i] + c);
if (a[i] >= cBase)
{ {
a[i] = (BYTE)(b[i]-(a[i]+c)); a[i] += cBase;
if (a[i]>=10) { a[i]+=10; c=1; } else c=0; c = 1;
} }
else
c = 0;
} }
else Chipset.carry = (c==1);
{
for (i=0; i<s; i++)
{
a[i] = (BYTE)(b[i]-(a[i]+c));
if (a[i]>=16) { a[i]+=16; c=1; } else c=0;
}
}
if (c==1)
Chipset.carry=TRUE;
else
Chipset.carry=FALSE;
} }
// 25.03.98 cg, end of new implementation
static __inline void Nand(BYTE *a, BYTE *b, UINT s) static __inline void Nand(BYTE *a, BYTE *b, UINT s)
{ {
@ -265,41 +247,34 @@ static __inline void Nor(BYTE *a, BYTE *b, UINT s)
while (s--) a[s]|=b[s]; while (s--) a[s]|=b[s];
} }
// 25.03.98 cg, optimized, new implementation
static __inline void Nnot(BYTE *a, UINT s) static __inline void Nnot(BYTE *a, UINT s)
{ {
if (Chipset.mode_dec) BYTE cBase = Chipset.mode_dec ? 9 : 15;
while (s--) (BYTE)(a[s]=9-a[s]);
else while (s--) a[s] = cBase - a[s];
while (s--) (BYTE)(a[s]=15-a[s]);
Chipset.carry = FALSE; Chipset.carry = FALSE;
} }
// 25.03.98 cg, end of new implementation
// 25.03.98 cg, optimized, new implementation
static __inline void Nneg(BYTE *a, UINT s) static __inline void Nneg(BYTE *a, UINT s)
{ {
UINT i; UINT i;
BYTE cBase = Chipset.mode_dec ? 10 : 16;
for (i=0; i<s; i++) if (a[i]) break;
if (i==s) for (i=0; i<s && a[i]==0; ++i) { } // search for non-zero digit
{ // it was 0 if (Chipset.carry = (i!=s)) // value was non-zero
Chipset.carry=FALSE;
return;
}
Chipset.carry=TRUE;
if (Chipset.mode_dec)
{ {
a[i] = (BYTE)(10-a[i]); /* first non-zero */ a[i] = cBase - a[i]; // first non-zero digit
for (i++; i<s; i++) a[i]=(BYTE)(9-a[i]); for (--cBase, ++i; i<s; i++)
} a[i] = cBase - a[i];
else
{
a[i] = (BYTE)(16-a[i]); /* first non-zero */
for (i++; i<s; i++) a[i]=(BYTE)(15-a[i]);
} }
} }
// 25.03.98 cg, end of new implementation
static __inline void Nsl(BYTE *a, UINT s) static __inline void Nsl(BYTE *a, UINT s)
{ {
while (--s) a[s]=a[s-1]; while (--s) a[s]=a[s-1];
(*a)=0; (*a)=0;
} }
@ -315,7 +290,6 @@ static __inline void Nslc(BYTE *a, UINT s)
static __inline void Nsr(BYTE *a, UINT s) static __inline void Nsr(BYTE *a, UINT s)
{ {
if (*a) Chipset.HST|=SB; if (*a) Chipset.HST|=SB;
while (--s) { (*a)=a[1]; a++; } while (--s) { (*a)=a[1]; a++; }
(*a)=0; (*a)=0;
@ -330,8 +304,7 @@ static __inline void Nsrc(BYTE *a, UINT s)
} }
static __inline void Nsrb(BYTE *a, UINT s) static __inline void Nsrb(BYTE *a, UINT s)
{ {
if ((*a)&1) Chipset.HST|=SB; if ((*a)&1) Chipset.HST|=SB;
while (--s) while (--s)
{ {

View file

@ -3,6 +3,7 @@
// //
#include <windows.h> #include <windows.h>
#include <shellapi.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <direct.h> #include <direct.h>

80
sources/Emu48/RESOURCE.H Normal file
View file

@ -0,0 +1,80 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Emu48.rc
//
#define IDI_EMU48 100
#define IDR_MENU 101
#define IDB_EMPTY 102
#define IDD_ABOUT 103
#define IDD_ABOUTS 104
#define IDD_SETTINGS 105
#define IDD_CHOOSEKML 106
#define IDD_KMLLOG 107
#define IDD_REGISTER 108
#define IDD_DISASM 109
#define IDC_PORT1WR 1000
#define IDC_AUTOSAVE 1001
#define IDC_AUTOSAVEONEXIT 1002
#define IDC_EMU48DIR 1003
#define IDC_KMLSCRIPT 1004
#define IDC_AUTHOR 1005
#define IDC_TITLE 1006
#define IDC_KMLLOG 1007
#define IDC_VERSION 1008
#define IDC_PORT2ISSHARED 1009
#define IDC_PORT2 1010
#define IDC_ALWAYSDISPLOG 1011
#define IDC_NAME 1012
#define IDC_REGTEXT 1013
#define IDC_CODE 1014
#define IDC_REGISTER 1015
#define IDC_UPDATE 1016
#define IDC_LICENSE 1017
#define IDC_REALSPEED 1018
#define IDC_PORT1EN 1019
#define IDC_WIRE 1020
#define IDC_IR 1021
#define IDC_DISASM_WIN 1022
#define IDC_DISASM_MAP 1023
#define IDC_DISASM_ROM 1024
#define IDC_DISASM_RAM 1025
#define IDC_DISASM_PORT1 1026
#define IDC_DISASM_PORT2 1027
#define IDC_DISASM_MODULE 1028
#define IDC_DISASM_HP 1029
#define IDC_DISASM_CLASS 1030
#define IDC_DISASM_MNEMONICS 1031
#define IDC_ADDRESS 1032
#define IDC_DISASM_ADR 1033
#define IDC_DISASM_NEXT 1034
#define IDC_DISASM_COPY 1035
#define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003
#define ID_FILE_SAVEAS 40004
#define ID_FILE_EXIT 40005
#define ID_VIEW_COPY 40006
#define ID_VIEW_SETTINGS 40007
#define ID_VIEW_RESET 40008
#define ID_OBJECT_LOAD 40009
#define ID_OBJECT_SAVE 40010
#define ID_ABOUT 40011
#define ID_FILE_CLOSE 40013
#define ID_BACKUP_SAVE 40014
#define ID_BACKUP_RESTORE 40015
#define ID_BACKUP_DELETE 40016
#define ID_VIEW_SCRIPT 40017
#define ID_STACK_COPY 40019
#define ID_STACK_PASTE 40020
#define ID_TOOL_DISASM 40021
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40022
#define _APS_NEXT_CONTROL_VALUE 1036
#define _APS_NEXT_SYMED_VALUE 108
#endif
#endif

View file

@ -9,7 +9,6 @@
#include "pch.h" #include "pch.h"
#include "Emu48.h" #include "Emu48.h"
//| SX | GX | Name //| SX | GX | Name
//#7056A #806E9 =TEMPOB //#7056A #806E9 =TEMPOB
//#7056F #806EE =TEMPTOP //#7056F #806EE =TEMPTOP
@ -161,29 +160,31 @@ DWORD RPL_CreateTemp(DWORD l)
l += 6; l += 6;
a = Read5(TEMPTOP); a = Read5(TEMPTOP);
b = Read5(RSKTOP); // start of available mem b = Read5(RSKTOP); // start of available mem
c = Read5(DSKTOP); // end of available mem c = Read5(DSKTOP); // end of available mem
if ((b+l)>c) return 0; // check if there is enough memory if ((b+l)>c) return 0; // check if there is enough memory
Write5(TEMPTOP, a+l); // adjust end of temporary objects Write5(TEMPTOP, a+l); // adjust end of temporary objects
Write5(RSKTOP, b+l); // adjust start of available mem Write5(RSKTOP, b+l); // adjust start of available mem
Write5(AVMEM, (c-(b+l))/5); // free memory (*5 nibbles) Write5(AVMEM, (c-(b+l))/5); // free memory (*5 nibbles)
p = (BYTE*)LocalAlloc(0,b-a); p = (BYTE*)LocalAlloc(0,b-a);
Npeek(p,a,b-a); Npeek(p,a,b-a);
Nwrite(p,a+l,b-a); Nwrite(p,a+l,b-a);
LocalFree(p); LocalFree(p);
Write5(a+l-5,l); // set temporary object length field Write5(a+l-5,l); // set temporary object length field
return (a+1); // return temporary object address return (a+1); // return temporary object address
} }
DWORD RPL_Pick(UINT l) DWORD RPL_Pick(UINT l)
{ {
DWORD stkp; DWORD stkp;
_ASSERT(l > 0); // 12.11.98 cg, new, first stack elememt is one
if (l==0) return 0; if (l==0) return 0;
stkp = Read5(DSKTOP) + (l-1)*5; stkp = Read5(DSKTOP) + (l-1)*5;
return Read5(stkp); return Read5(stkp);
} }
#if 0 // 12.11.98 cg, function not needed yet
VOID RPL_Replace(DWORD n) VOID RPL_Replace(DWORD n)
{ {
DWORD stkp; DWORD stkp;
@ -192,18 +193,19 @@ VOID RPL_Replace(DWORD n)
Write5(stkp,n); Write5(stkp,n);
return; return;
} }
#endif
VOID RPL_Push(DWORD n) VOID RPL_Push(DWORD n)
{ {
DWORD stkp, avmem; DWORD stkp, avmem;
avmem = Read5(AVMEM); avmem = Read5(AVMEM); // amount of free memory
if (avmem==0) return; if (avmem==0) return; // no memory free
avmem--; avmem--; // fetch memory
Write5(AVMEM,avmem); Write5(AVMEM,avmem); // save new amount of free memory
stkp = Read5(DSKTOP); stkp = Read5(DSKTOP); // get pointer to stack level 1
stkp-=5; stkp-=5; // fetch new stack entry
Write5(stkp,n); Write5(stkp,n); // save pointer to new object on stack level 1
Write5(DSKTOP,stkp); Write5(DSKTOP,stkp); // save new pointer to stack level 1
return; return;
} }

231
sources/Emu48/SERIAL.C Normal file
View file

@ -0,0 +1,231 @@
/*
* Serial.c
*
* This file is part of Emu48
*
* Copyright (C) 1998 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
#include "Serial.h"
#define INTERRUPT ((void)(Chipset.SoftInt=TRUE,bInterrupt=TRUE))
static OVERLAPPED os = { 0 };
static HANDLE hComm = NULL;
static HANDLE hCThread = NULL;
static DWORD lSerialThreadId = 0;
static BOOL bReading = TRUE;
static WORD wPort = PORT_CLOSE;
static CRITICAL_SECTION csRecv; // 01.06.98 cg, new, critical section for receive byte
static DWORD WINAPI SerialThread(LPVOID pParam)
{
DWORD dwEvent;
SetCommMask(hComm,EV_RXCHAR); // event on RX
while (bReading)
{
_ASSERT(hComm != NULL);
WaitCommEvent(hComm,&dwEvent,NULL); // wait for serial event
if (dwEvent & EV_RXCHAR) // signal char received
{
CommReceive(); // get data
// interrupt request and emulation thread down
if (Chipset.SoftInt && Chipset.Shutdn)
ResumeThread(hThread); // wake up emulation thread
}
}
lSerialThreadId = 0; // signal serial thread is down
return 0;
UNREFERENCED_PARAMETER(pParam);
}
WORD CommConnect(VOID)
{
return wPort;
}
VOID CommOpen(LPSTR strWirePort,LPSTR strIrPort)
{
COMMTIMEOUTS CommTimeouts = { MAXDWORD, 0L, 0L, 0L, 0L };
LPSTR strPort = (Chipset.IORam[IR_CTRL] & EIRU) ? strIrPort : strWirePort;
if (hComm != NULL) // port already open
CloseHandle(hComm);
if (strcmp(strPort,NO_SERIAL)) // port defined
{
hComm = CreateFile(strPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if(hComm != INVALID_HANDLE_VALUE)
{
// 01.06.98 cg, bugfix, initialize critical section
InitializeCriticalSection(&csRecv);
wPort = (Chipset.IORam[IR_CTRL] & EIRU) ? PORT_IR : PORT_WIRE;
SetCommTimeouts(hComm,&CommTimeouts);
CommSetBaud();
// set event RXD handler
bReading = TRUE;
hCThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&SerialThread,NULL,0,&lSerialThreadId);
_ASSERT(lSerialThreadId);
}
else
hComm = NULL;
}
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"COM port %s.\n",hComm ? "opened": "open error");
OutputDebugString(buffer);
}
#endif
}
VOID CommClose(VOID)
{
if (hComm != NULL) // port open
{
bReading = FALSE; // kill read thread
SetCommMask(hComm,0L); // clear all events and force WaitCommEvent to return
while (lSerialThreadId != 0) Sleep(0); // wait for termination
CloseHandle(hComm); // close port
hComm = NULL;
#if defined DEBUG_SERIAL
OutputDebugString("COM port closed.\n");
#endif
DeleteCriticalSection(&csRecv); // 01.06.98 cg, bugfix, release critical section
wPort = PORT_CLOSE;
}
}
VOID CommSetBaud(VOID)
{
if (hComm != NULL)
{
const DWORD dwBaudrates[] = { 1200, 1920, 2400, 3840, 4800, 7680, 9600, 15360 };
DCB dcb;
FillMemory(&dcb,sizeof(dcb),0);
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = dwBaudrates[Chipset.IORam[BAUD] & 0x7];
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fOutX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE; // may changed in further implementations
dcb.ByteSize = 8;
dcb.Parity = NOPARITY; // no parity check, emulated by software
dcb.StopBits = ONESTOPBIT;
#if defined DEBUG_SERIAL
{
char buffer[256];
wsprintf(buffer,"CommsetBaud: %ld\n",dcb.BaudRate);
OutputDebugString(buffer);
}
#endif
SetCommState(hComm,&dcb);
}
}
VOID CommTransmit(VOID)
{
DWORD dwWritten;
BYTE tbr = (Chipset.IORam[TBR_MSB] << 4) | Chipset.IORam[TBR_LSB];
#if defined DEBUG_SERIAL
{
char buffer[256];
if (isprint(tbr))
wsprintf(buffer,"-> '%c'\n",tbr);
else
wsprintf(buffer,"-> %02X\n",tbr);
OutputDebugString(buffer);
}
#endif
if (hComm != NULL) // wire com port open
WriteFile(hComm,(LPCVOID) &tbr,1,&dwWritten,&os);
Chipset.IORam[TCS] &= (~TBF); // clear transmit buffer
if (Chipset.IORam[IO_CTRL] & ETBE) // interrupt on transmit buffer empty
INTERRUPT;
}
VOID CommReceive(VOID)
{
static BYTE cBuffer[128];
static WORD nRp;
static DWORD dwBytesRead = 0L;
if (hComm == NULL) // not open
return;
if (!(Chipset.IORam[IO_CTRL] & SON)) // UART off
{
dwBytesRead = 0L; // no bytes received
return;
}
EnterCriticalSection(&csRecv); // 01.06.98 cg, bugfix, synchronize
do
{
if (Chipset.IORam[RCS] & RBF) // receive buffer full
break;
if (dwBytesRead == 0L) // buffer empty
{
if(ReadFile(hComm,&cBuffer,sizeof(cBuffer),&dwBytesRead,&os) == FALSE)
dwBytesRead = 0L;
else // bytes received
nRp = 0; // reset read pointer
}
if(dwBytesRead == 0L) // receive buffer empty
break;
#if defined DEBUG_SERIAL
{
char buffer[256];
if (isprint(cBuffer[nRp]))
wsprintf(buffer,"<- '%c'\n",cBuffer[nRp]);
else
wsprintf(buffer,"<- %02X\n",cBuffer[nRp]);
OutputDebugString(buffer);
}
#endif
Chipset.IORam[RBR_MSB] = (cBuffer[nRp] >> 4);
Chipset.IORam[RBR_LSB] = (cBuffer[nRp] & 0x0f);
++nRp;
--dwBytesRead;
Chipset.IORam[RCS] |= RBF; // receive buffer full
if (Chipset.IORam[IO_CTRL] & ERBF) // interrupt on recv buffer full
INTERRUPT;
}
while(0);
LeaveCriticalSection(&csRecv); // 01.06.98 cg
}

44
sources/Emu48/SERIAL.H Normal file
View file

@ -0,0 +1,44 @@
/*
* Serial.h
*
* This file is part of Emu48
*
* Copyright (C) 1998 Christoph Gießelink
*
*/
// UART addresses without mapping offset
#define BAUD 0x0d // Baudrate (Bit 2-0)
#define IO_CTRL 0x10 // IO CONTROL
#define RCS 0x11 // RCS
#define TCS 0x12 // TCS
#define CRER 0x13 // CRER
#define RBR_LSB 0x14 // RBR low nibble
#define RBR_MSB 0x15 // RBR high nibble
#define TBR_LSB 0x16 // TBR low nibble
#define TBR_MSB 0x17 // TBR high nibble
#define IR_CTRL 0x1a // IR CONTROL
// 0x10 Serial I/O Control [SON ETBE ERBF ERBZ]
#define SON 0x08 // Serial on
#define ETBE 0x04 // Interrupt on transmit buffer empty
#define ERBF 0x02 // Interrupt on receive buffer full
#define ERBZ 0x01 // Interrupt on receiver busy
// 0x11 Serial Receive Control/Status [RX RER RBZ RBF]
#define RX 0x08 // ??? Rx pin high (read-only)
#define RER 0x04 // Receiver error
#define RBZ 0x02 // Receiver busy
#define RBF 0x01 // Receive buffer full
// 0x12 Serial Transmit Control/Status [BRK LPB TBZ TBF]
#define BRK 0x08
#define LPB 0x04
#define TBZ 0x02 // Transmitter busy
#define TBF 0x01 // Transmit buffer full
// 0x1a IR Control Register [IRI EIRU EIRI IRE]
#define IRI 0x08 // IR input (read-only)
#define EIRU 0x04 // Enable IR UART mode
#define EIRI 0x02 // Enable IR interrupt
#define IRE 0x01 // IR event

403
sources/Emu48/TIMER.C Normal file
View file

@ -0,0 +1,403 @@
/*
* timer.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "Emu48.h"
#define AUTO_OFF 10 // 25.02.98 cg, new, Time in minutes for 'auto off'
// 25.02.98 cg, new, Ticks for 01.01.1970 00:00:00
#define UNIX_0_TIME 0x0001cf2e8f800000
// 25.02.98 cg, new, Ticks for 'auto off'
#define OFF_TIME ((LONGLONG) (AUTO_OFF * 60) << 13)
// 30.09.98 cg, new, memory address for clock and auto off
// S(X) = 0x70052-0x70070, G(X) = 0x80058-0x80076
#define RPLTIME ((cCurrentRomType=='S')?0x52:0x58)
#define T1_FREQ 62 // 10.11.98 cg, new, Timer1 1/frequency in ms
#define T2_FREQ 8192 // 06.04.98 cg, new, Timer2 frequency
// 27.02.98 cg, new, Timer definitions
// Timer addresses without mapping offset
#define TIMER1_CTRL 0x2e // Timer1 Control
#define TIMER2_CTRL 0x2f // Timer2 Control
#define TIMER1 0x37 // Timer1 (4 bit)
#define TIMER2 0x3f // Timer2 (32 bit, LSB first)
// 0x2e Timer1 Control [SRQ WKE INT XTRA]
#define SRQ 0x08 // Service request
#define WKE 0x04 // Wake up
#define INT 0x02 // Interrupt
#define XTRA 0x01 // Extra function
// 0x2f Timer2 Control [SRQ WKE INT RUN]
#define SRQ 0x08 // Service request
#define WKE 0x04 // Wake up
#define INT 0x02 // Interrupt
#define RUN 0x01 // Timer run
// BOOL bAccurateTimer = TRUE; // 10.11.98 cg, removed, not adjustable any more
// UINT uT1Period = 62; // 10.11.98 cg, removed, not adjustable any more
static BOOL bStarted = FALSE;
static BOOL bOutRange = FALSE; // 21.04.98 cg, new, flag if timer value out of range
static UINT uT1TimerId = 0;
static UINT uT2TimerId = 0;
// static DWORD dwT1Ticks = 0; // 19.02.98 cg, removed, not used
// static DWORD dwT2Init = 0; // 06.04.98 cg, removed, not used any more
// static DWORD dwT2Step = 0; // 06.04.98 cg, removed, not used any more
// static DWORD dwT2Ticks = 0; // 06.04.98 cg, removed, not used any more
static BOOL bAccurateTimer; // 10.11.98 cg, new, flag if accurate timer is used
static LARGE_INTEGER lT2Ref; // 06.04.98 cg, new, counter value at timer2 start
static TIMECAPS tc; // 21.04.98 cg, new, timer information
static __inline MAX(int a, int b) {return (a>b)?a:b;}
static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2);
static VOID SetAccesstime(VOID) // 06.10.97 cg, new, set date and time
{
SYSTEMTIME ts;
LONGLONG ticks, time;
DWORD dw;
WORD crc, i;
BYTE p[4];
_ASSERT(sizeof(LONGLONG) == 8); // check size of datatype
GetLocalTime(&ts); // local time, _ftime() cause memory/resource leaks
// calculate days until 01.01.1970
dw = (DWORD) ts.wMonth;
if (dw > 2)
dw -= 3L;
else
{
dw += 9L;
--ts.wYear;
}
dw = (DWORD) ts.wDay + (153L * dw + 2L) / 5L;
dw += (146097L * (((DWORD) ts.wYear) / 100L)) / 4L;
dw += (1461L * (((DWORD) ts.wYear) % 100L)) / 4L;
dw -= 719469L;
// convert into seconds and add time
dw = dw * 24L + (DWORD) ts.wHour;
dw = dw * 60L + (DWORD) ts.wMinute;
dw = dw * 60L + (DWORD) ts.wSecond;
// create timerticks = (s + ms) * 8192
ticks = ((LONGLONG) dw << 13) | (((LONGLONG) ts.wMilliseconds << 10) / 125);
ticks += UNIX_0_TIME; // add offset ticks from year 0
ticks += (LONG) Chipset.t2; // add actual timer2 value
time = ticks; // save for calc. timeout
time += OFF_TIME; // add 10 min for auto off
dw = RPLTIME; // 30.09.98, bugfix, HP addresses for clock in port0
crc = 0x0; // reset crc value
for (i = 0; i < 13; ++i, ++dw) // write date and time
{
*p = (BYTE) ticks & 0xf;
crc = (crc >> 4) ^ (((crc ^ ((WORD) *p)) & 0xf) * 0x1081);
Chipset.Port0[dw] = *p; // 30.09.98, bugfix, always store in port0
ticks >>= 4;
}
Nunpack(p,crc,4); // write crc
memcpy(Chipset.Port0+dw,p,4); // 30.09.98, bugfix, always store in port0
dw += 4; // HP addresses for timeout
for (i = 0; i < 13; ++i, ++dw) // write time for auto off
{
// 30.09.98, bugfix, always store in port0
Chipset.Port0[dw] = (BYTE) time & 0xf;
time >>= 4;
}
Chipset.Port0[dw] = 0xf; // 30.09.98, bugfix, always store in port0
return;
}
static DWORD CalcT2(VOID) // 21.04.98 cg, new, calculate timer2 value
{
DWORD dwT2 = Chipset.t2; // get value from chipset
if (bStarted) // timer2 running
{
LARGE_INTEGER lT2Act;
QueryPerformanceCounter(&lT2Act); // actual time
// calculate ticks since reference point
dwT2 -= (DWORD)
(((lT2Act.QuadPart - lT2Ref.QuadPart) * T2_FREQ)
/ lFreq.QuadPart);
}
return dwT2;
}
static VOID CheckT1(BYTE nT1) // 25.11.98 cg, bugfix, changed implementation
{
if ((nT1&8) == 0) // timer1 MSB not set
{
Chipset.IORam[TIMER1_CTRL] &= ~SRQ; // clear SRQ bit
return;
}
_ASSERT((nT1&8) != 0); // timer1 MSB set
// timer MSB is one and either INT or WAKE is set
if ( (Chipset.IORam[TIMER1_CTRL]&WKE)
|| (Chipset.IORam[TIMER1_CTRL]&INT))
Chipset.IORam[TIMER1_CTRL] |= SRQ; // set SRQ
// cpu not sleeping and T1 -> Interrupt
if ( (!Chipset.Shutdn || (Chipset.IORam[TIMER1_CTRL]&WKE))
&& (Chipset.IORam[TIMER1_CTRL]&INT))
{
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
// cpu sleeping and T1 -> Wake Up
if (Chipset.Shutdn && (Chipset.IORam[TIMER1_CTRL]&WKE))
{
Chipset.IORam[TIMER1_CTRL] &= ~WKE; // clear WKE bit
ResumeThread(hThread); // wake up emulation thread
}
return;
}
static VOID CheckT2(DWORD dwT2) // 25.11.98 cg, bugfix, changed implementation
{
if ((dwT2&0x80000000) == 0) // timer2 MSB not set
{
Chipset.IORam[TIMER2_CTRL] &= ~SRQ; // clear SRQ bit
return;
}
_ASSERT((dwT2&0x80000000) != 0); // timer2 MSB set
// timer MSB is one and either INT or WAKE is set
if ( (Chipset.IORam[TIMER2_CTRL]&WKE)
|| (Chipset.IORam[TIMER2_CTRL]&INT))
Chipset.IORam[TIMER2_CTRL] |= SRQ; // set SRQ
// cpu not sleeping and T2 -> Interrupt
if ( (!Chipset.Shutdn || (Chipset.IORam[TIMER2_CTRL]&WKE))
&& (Chipset.IORam[TIMER2_CTRL]&INT))
{
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
// cpu sleeping and T2 -> Wake Up
if (Chipset.Shutdn && (Chipset.IORam[TIMER2_CTRL]&WKE))
{
Chipset.IORam[TIMER2_CTRL] &= ~WKE; // clear WKE bit
ResumeThread(hThread); // wake up emulation thread
}
return;
}
static VOID RescheduleT2(BOOL bRefPoint) // 21.04.98 cg, add function parameter
{
UINT uDelay;
_ASSERT(uT2TimerId == 0); // timer2 must stopped
// 29.09.98 cg, bugfix, changed implementation
if (bRefPoint) // save reference time
{
QueryPerformanceCounter(&lT2Ref); // time of corresponding Chipset.t2 value
uDelay = Chipset.t2; // timer value for delay
}
else // called without new refpoint, restart t2 with actual value
{
uDelay = CalcT2(); // actual timer value for delay
}
uDelay &= 0x7FFFFFFF; // 24.11.98 cg, bugfix, execute timer2 event when MSB change
uDelay >>= 3; // timer delay in ms
uDelay = MAX(tc.wPeriodMin,uDelay); // wait minimum delay of timer
if (bOutRange = uDelay > tc.wPeriodMax) // delay greater maximum delay
uDelay = tc.wPeriodMax; // wait maximum delay time
// 29.09.98 cg, end of changed implementation
// dwT2Init = timeGetTime(); // 06.04.98 cg, not used any more
// dwT2Ticks = dwT2Init; // 06.04.98 cg, not used any more
// start timer2; schedule event, when Chipset.t2 will be zero (Chipset.t2 / 8 = time in ms)
uT2TimerId = timeSetEvent(uDelay,0,(LPTIMECALLBACK)&TimeProc,2,TIME_ONESHOT);
_ASSERT(uT2TimerId); // 21.04.98 cg, new, test if timer2 started
return;
}
static VOID AbortT2(VOID)
{
_ASSERT(uT2TimerId);
timeKillEvent(uT2TimerId); // 09.10.97 cg, bugfix, first kill event
uT2TimerId = 0; // 09.10.97 cg, bugfix, then reset var
return;
}
static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
_ASSERT(uEventId); // 16.03.98 cg, new, illegal EventId
if (!bStarted) // timer stopped
return; // -> quit
// called from timer1 event (default period 16 Hz)
// if ((uT1TimerId!=0) && (uEventId == uT1TimerId))
if (uEventId == uT1TimerId) // 16.03.98 cg, removed useless part
{
EnterCriticalSection(&csT1Lock); // 21.04.98 cg, bugfix, synchronize
{
Chipset.t1 = (Chipset.t1-1)&0xF;// decrement timer value
CheckT1(Chipset.t1); // test timer1 control bits
}
LeaveCriticalSection(&csT1Lock); // 21.04.98 cg
return;
}
// called from timer2 event, Chipset.t2 should be zero
// if ((uT2TimerId!=0) && (uEventId == uT2TimerId))
if (uEventId == uT2TimerId) // 16.03.98 cg, removed useless part
{
EnterCriticalSection(&csT2Lock); // 21.04.98 cg, bugfix, synchronize
{
uT2TimerId = 0; // 30.11.98 cg, bugfix, single shot timer timer2 stopped
if (!bOutRange) // 21.04.98 cg, timer event elapsed
{
// timer2 overrun, test timer2 control bits else restart timer2
// 16.11.98 cg, bugfix, don't wait for timer2 overrun any more
Chipset.t2 = CalcT2(); // calculate new timer2 value
CheckT2(Chipset.t2); // test timer2 control bits
}
RescheduleT2(!bOutRange); // restart timer2
}
LeaveCriticalSection(&csT2Lock); // 21.04.98 cg
return;
}
return;
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(dwUser); // 19.02.98 cg, added unreferenced parameter declarations
UNREFERENCED_PARAMETER(dw1);
UNREFERENCED_PARAMETER(dw2);
}
VOID StartTimers(VOID)
{
if (bStarted) // timer running
return; // -> quit
if (Chipset.IORam[TIMER2_CTRL]&RUN) // start timer1 and timer2 ?
{
bStarted = TRUE; // flag timer running
SetAccesstime(); // 06.10.97 cg, set date and time
// 10.11.98 cg, changed, use always accurate timer
// if (bAccurateTimer) // box "Accurate timer" checked
// {
// 21.04.98 cg, optimized, set timer resolution to 1 ms, if failed don't use "Accurate timer"
bAccurateTimer = (timeBeginPeriod(1) == TIMERR_NOERROR);
// }
timeGetDevCaps(&tc,sizeof(tc)); // 21.04.98 cg, get timer resolution
// set timer1 with given period
// 10.11.98 cg, changed, use fix event time
uT1TimerId = timeSetEvent(T1_FREQ,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC);
_ASSERT(uT1TimerId); // 16.03.98 cg, new, test if timer1 started
RescheduleT2(TRUE); // start timer2
}
return;
}
VOID StopTimers(VOID)
{
if (!bStarted) // timer stopped
return; // -> quit
// Chipset.t2 = ReadT2(); // 21.04.98 cg, removed, read timer2 value later
if (uT1TimerId != 0) // timer1 running
{
// 02.12.98 cg, bugfix, Critical Section handler may cause a dead lock
timeKillEvent(uT1TimerId); // stop timer1
uT1TimerId = 0; // set flag timer1 stopped
// 02.12.98 cg, end of bugfix
}
if (uT2TimerId != 0) // timer2 running
{
EnterCriticalSection(&csT2Lock); // 21.04.98 cg, bugfix, synchronize
{
Chipset.t2 = CalcT2(); // 21.04.98 cg, update chipset timer2 value
// AbortT2(); // 02.12.98 cg, removed, stop timer2 later
}
LeaveCriticalSection(&csT2Lock); // 21.04.98 cg
AbortT2(); // 02.12.98 cg, bugfix, stop timer2 here
}
bStarted = FALSE;
if (bAccurateTimer) // "Accurate timer" running
{
timeEndPeriod(1); // finish service
}
return;
}
DWORD ReadT2(VOID)
{
// 21.04.98 cg, changed implementation
DWORD dwT2;
EnterCriticalSection(&csT2Lock);
{
// 16.12.98 cg, bugfix, calculate timer2 value or if stopped last timer value
dwT2 = bStarted ? CalcT2() : Chipset.t2;
CheckT2(dwT2); // 25.11.98 cg, new, update timer2 control bits
}
LeaveCriticalSection(&csT2Lock);
return dwT2;
}
VOID SetT2(DWORD dwValue)
{
// calling AbortT2() inside Critical Section handler may cause a dead lock
if (uT2TimerId != 0) // 02.12.98 cg, bugfix, timer2 running
AbortT2(); // 02.12.98 cg, bugfix, stop timer2
// 21.04.98 cg, changed implementation
EnterCriticalSection(&csT2Lock);
{
// if (uT2TimerId != 0) // 02.12.98 cg, removed, done before
// AbortT2(); // 02.12.98 cg, removed, done before
Chipset.t2 = dwValue; // set new value
CheckT2(Chipset.t2); // 25.11.98 cg, readded, test timer2 control bits
if (bStarted) // timer running
RescheduleT2(TRUE); // restart timer2
}
LeaveCriticalSection(&csT2Lock);
return;
}
BYTE ReadT1(VOID)
{
BYTE nT1;
EnterCriticalSection(&csT1Lock); // 21.04.98 cg, bugfix, synchronize
{
nT1 = Chipset.t1; // read timer1 value
CheckT1(nT1); // 25.11.98 cg, new, update timer1 control bits
}
LeaveCriticalSection(&csT1Lock); // 21.04.98 cg
return nT1;
}
VOID SetT1(BYTE byValue)
{
timeKillEvent(uT1TimerId); // 11.06.98 cg, bugfix, stop timer1
uT1TimerId = 0; // 11.06.98 cg, new, set flag timer1 stopped
EnterCriticalSection(&csT1Lock); // 21.04.98 cg, bugfix, synchronize
{
Chipset.t1 = byValue&0xF; // set new timer1 value
CheckT1(Chipset.t1); // 25.11.98 cg, readded, test timer1 control bits
}
LeaveCriticalSection(&csT1Lock); // 21.04.98 cg
// 11.06.98 cg, bugfix, restart timer1
// 10.11.98 cg, changed, use fix event time
uT1TimerId = timeSetEvent(T1_FREQ,0,(LPTIMECALLBACK)&TimeProc,1,TIME_PERIODIC);
_ASSERT(uT1TimerId); // 11.06.98 cg, new, test if timer1 started
return;
}

92
sources/Emu48/TYPES.H Normal file
View file

@ -0,0 +1,92 @@
/*
* types.h
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#define CHIPSET Chipset_t
typedef struct
{
WORD wPosX;
WORD wPosY;
BYTE type;
DWORD Port0Size; // real size of module im KB
DWORD Port1Size; // real size of module im KB
DWORD Port2Size; // 27.06.98 cg, not used any more
LPBYTE Port0;
LPBYTE Port1;
LPBYTE Port2;
DWORD pc;
DWORD d0;
DWORD d1;
DWORD rstkp;
DWORD rstk[8];
BYTE A[16];
BYTE B[16];
BYTE C[16];
BYTE D[16];
BYTE R0[16];
BYTE R1[16];
BYTE R2[16];
BYTE R3[16];
BYTE R4[16];
BYTE ST[4];
BYTE HST;
BYTE P;
WORD out;
WORD in;
BOOL SoftInt;
BOOL Shutdn;
BOOL mode_dec;
BOOL inte; // interrupt status flag (FALSE = int in service)
BOOL intk; // 1 ms keyboard scan flag (TRUE = enable)
BOOL intd; // keyboard interrupt pending (TRUE = int pending)
BOOL carry;
WORD crc;
// UINT uUnused1; // 21.02.99 cg, removed, not used
WORD wPort2Crc; // 21.02.99 cg, new, fingerprint of port2
WORD wUnused1; // 21.02.99 cg, new, dummy to fill rest of old variable
// UINT Port2_Size; // 25.02.99 cg, removed, not used
DWORD dwKdnCycles; // 25.02.99 cg, cpu cycles at start of 1ms key handler
BOOL Port1_Writeable;
BOOL Port2_Writeable; // 30.05.98 cg, not used
UINT Port2_Bank; // 15.12.98 cg, new, save state of GX port2 FF
UINT Port2_NBanks; // 30.05.98 cg, not used
BYTE cards_status;
BYTE IORam[64]; // I/O hardware register
UINT IOBase; // address of I/O modules page
BOOL IOCfig; // I/O module configuration flag
BYTE P0Base, BSBase, P1Base, P2Base; // address of modules first 2KB page
BYTE P0Size, BSSize, P1Size, P2Size; // mapped size of module in 2KB
BYTE P0End, BSEnd, P1End, P2End; // address of modules last 2KB page
BOOL P0Cfig, BSCfig, P1Cfig, P2Cfig; // module address configuration flag
BOOL P0Cfg2, BSCfg2, P1Cfg2, P2Cfg2; // module size configuration flag
BYTE t1;
DWORD t2;
// DWORD t2_ticks; // 03.03.98 cg, removed, not used
DWORD cycles; // 03.03.98 cg, new, oscillator cycles
BYTE Keyboard_Row[9];
WORD IR15X;
UINT Keyboard_State; // 30.05.98 cg, not used
signed short loffset;
signed int width;
UINT boffset;
UINT lcounter;
UINT sync; // 24.08.98 cg, not used
BYTE contrast;
BOOL dispon;
DWORD start1;
DWORD start12;
DWORD end1;
DWORD start2, end2;
} Chipset_t;